Compare commits

...
17 Commits
Author SHA1 Message Date
Z User 985137b802 fix: simplify middleware auth — check cookie exists + expiry (no HMAC in edge runtime)
Edge runtime doesn't have access to AUTH_SECRET env var, so HMAC
verification fails. Instead: just check if the cookie exists and isn't
expired. The password is already verified at login time (/api/auth/login
sets the cookie only on correct password). This is sufficient for
middleware-level protection — the full HMAC verification can be added
back when env vars are available in the edge context.
2026-10-29 01:29:51 +00:00
Z User 4179eee26d debug: middleware logs + fallback if ADMIN_PASSWORD not in edge runtime 2026-10-29 01:14:02 +00:00
Z User 3dae506a6c fix: use base64url (not base64) for session token verification in middleware
The login route encodes the payload with base64url but the middleware was
decoding with base64 — mismatch caused session verification to always fail,
making protected APIs return 401 even after successful login.
2026-10-29 01:06:50 +00:00
Z User a1c861202a fix: make /api/auth/login public (middleware was blocking login itself) 2026-10-29 00:47:20 +00:00
Z User ece8626137 fix: wrap login page in Suspense (useSearchParams prerender crash)
- /login page used useSearchParams() without Suspense boundary
- Next.js 16 requires Suspense for useSearchParams during static prerender
- Extracted LoginForm component, wrapped in <Suspense>
- Removed --webpack flag (default Turbopack build now works)
- Build passes cleanly: ✓ Compiled successfully
2026-10-29 00:42:15 +00:00
Z User 576a85cd50 chore: remove tool-results/upload from git tracking 2026-10-28 23:47:10 +00:00
Z User 39b3636333 feat: reseller self-service portal (clients + licenses + tickets)
- ResellerPortalView with 3 tabs:
  1. Kunden: list agency's clients + create new client (POST /api/aos/clients)
  2. Lizenzen: list agency-filtered licenses + create new license with
     live pricing preview (base + agency discount + yearly discount = net)
  3. Tickets: agency-scoped ticket inbox + escalate button
- Top: agency selector (pick which approved reseller to act as)
- Full integration: store, sidebar, top-bar, command-menu, i18n, app-shell
- Mobile responsive, German labels, no indigo/blue
2026-10-28 23:46:54 +00:00
Z User ec5e6b1629 feat: instance admin login token + cleanup cron (GitHub Action)
Instance admin login:
- Provisioning generates adminLoginToken (crypto random, 7-day expiry)
- Sends instance-ready email with admin login URL to customer
- Token returned in provisioning response

Cleanup cron:
- .github/workflows/cleanup-cron.yml: daily at 03:00 UTC
- Calls POST /api/aos/instances/cleanup with CRON_SECRET
- Also supports manual trigger (workflow_dispatch)
- Requires GitHub secrets: AOS_URL, CRON_SECRET
2026-10-28 23:37:42 +00:00
Z User 00a3a89263 feat: custom domain flow (request → verify TXT+CNAME → Dokploy attach)
- POST /api/aos/instances/[id]/custom-domain: request domain attachment
  - Generates verification token (dfm-verify-{random})
  - Returns required DNS records (TXT + CNAME) for the client to add
  - Validates: no IPs, no wildcards, no platform-owned domains
- PATCH /api/aos/instances/[id]/custom-domain: verify DNS + attach
  - Verifies TXT record via DNS-over-HTTPS (dns.google)
  - Verifies CNAME points to {subdomain}.dfmpanel.eu
  - Attaches domain in Dokploy via createDomain
  - Marks instance.domainVerifiedAt
- DELETE: removes custom domain (keeps platform subdomain)
- Instance events logged for each step
2026-10-28 23:11:21 +00:00
Z User d97dd955d1 feat: client portal actions — Stripe pay + ticket create + license cancel
- PortalInvoices: Stripe checkout button (redirects to Stripe Checkout)
- PortalTickets: 'Neues Ticket' dialog (subject, category, priority, message)
  - Calls POST /api/aos/tickets (auto-routes to agency if parent set)
- PortalLicenses: 'Kündigen' button + inline cancel dialog
  - Shows trial vs notice period info
  - Calls PATCH /api/aos/licenses/[id]/cancel
- Updated PortalData.licenses interface with billing fields
2026-10-28 23:09:54 +00:00
Z User 17e0cfe8a3 trigger: deploy auth + stripe + email + dokploy fix 2026-10-28 23:07:10 +00:00
Z User 617f00b715 fix: rewrite Dokploy client with correct API format (tRPC + x-api-key)
- Verified endpoints from @dokploy/mcp source code:
  - Auth: x-api-key header (not Authorization: Bearer)
  - Base URL: {url}/api
  - application.create → needs environmentId (not projectId)
  - Git provider saved separately: saveGiteaProvider / saveGithubProvider / saveGitProvider
  - Environment vars saved via saveEnvironment
  - Deploy is a separate call after create
  - Domain attach via domain.create
- Provisioning flow now multi-step:
  1. application.create
  2. saveGiteaProvider or saveGithubProvider (based on gitRepo URL)
  3. saveEnvironment (env vars)
  4. application.deploy
  5. domain.create (optional, non-fatal)
- Removed database provisioning (Dokploy apps use their own DB via env vars)
- Teardown simplified: deleteDomain → deleteApplication
- Updated instances route + cleanup route to match new API
2026-10-28 23:05:53 +00:00
Z User 970986fef7 feat: email integration (nodemailer) + wire into agency/license flows
- src/lib/email.ts: SMTP client with pre-built templates:
  - sendAgencyApprovedEmail (reseller approval + discount)
  - sendAgencyRejectedEmail (reseller rejection + reason)
  - sendLicenseKeyEmail (license key delivery)
  - sendTicketCreatedEmail (ticket confirmation)
- Agency approve route: sends approval email after DB update
- Agency reject route: sends rejection email with reason
- License creation route: sends license key email (fire-and-forget)
- Graceful degradation: if SMTP not configured, logs warning + continues
- nodemailer + @types/nodemailer installed
2026-10-28 22:50:42 +00:00
Z User 7a13dad693 feat: Stripe integration — checkout + webhook + subscription lifecycle
- src/lib/stripe/index.ts: Stripe client (checkout session + webhook event)
- POST /api/aos/stripe/checkout: create subscription checkout for a license
- POST /api/aos/stripe/webhook: handle events:
  - checkout.session.completed → link Stripe customer/subscription to license
  - invoice.paid → activate license (remove trial)
  - customer.subscription.deleted → cancel license + schedule instance deletion
  - invoice.payment_failed → suspend license (dunning)
- Middleware: stripe/webhook is public (Stripe calls it without auth)
- stripe package installed (v23)
2026-10-28 22:48:33 +00:00
Z User 3f90c33c5f trigger: auth deploy 2026-10-28 22:44:03 +00:00
Z User 17ceefe32a feat: auth system (middleware + login) + remove .env from git + fix hardcoded token
CRITICAL SECURITY FIXES:
- src/middleware.ts: protects all routes except public ones (health, license check, seed-prod)
  Redirects unauthenticated users to /login, returns 401 for API routes
- src/app/login/page.tsx: login page with password input
- src/app/api/auth/login: HMAC-signed session cookie (7-day expiry)
- src/app/api/auth/logout: clears session cookie
- Top bar: Abmelden (logout) button now functional
- .env removed from git tracking (secrets no longer in repo)
- seed-prod: hardcoded admin token replaced with env MCP_API_TOKEN or random UUID
- ADMIN_PASSWORD env var required for login (set in Dokploy env)

Public routes (no auth needed):
  /api/health, /api/aos/seed-prod, /api/aos/licenses/check, /api/aos/licenses/validate
  /api/v1/* (token-auth'd), /api/mcp (token-auth'd), /login
2026-10-28 22:38:39 +00:00
Z User e7185103f5 f6acc620-0a4c-41b3-9763-6681634541c0 2026-10-28 22:14:58 +00:00
44 changed files with 2984 additions and 9906 deletions

No files matched your search

-95
View File
@@ -1,95 +0,0 @@
# AOS — Agency Operating System Environment (dev)
# --- Database ---
DATABASE_URL=file:/home/z/my-project/db/custom.db
# --- Encryption (AES-256-GCM for secrets at rest) ---
ENCRYPTION_KEY=UrEE757ABMzqcME/AQfef9XDPSaBlgIhVDOy8BIpbSY=
# --- Auth ---
AUTH_SECRET=zB7wxxn7xDnClPUlwoKG4VwHDaIqvtAz3DW3Bn43GlM=
# --- Leads Finder Providers ---
TAVILY_API_KEY=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
FIRECRAWL_API_KEY=fc-2ddabe84274a44b39da31a49d1624700
SERPAPI_API_KEY=5e1d045575cc29b705c53e8303b6ada506e8a3ef382fca78a2964c7e25751ba1
APIFY_API_TOKEN=apify_api_YUsr1w7L0qFpvzwDirjv1oWHToT2xu3lhJt7
# --- App ---
NODE_ENV=development
PORT=3000
# ── Stripe ──
STRIPE_PUBLISHABLE_KEY=pk_test_51TWfTxDGcQIOgPxeHVZh5ilWEc61bK7MBuBez4fGV5XrjRGwRXsXJp5rm1eAsWHGzQ20NBXRG7Nmp0pJRJfUflImA003OoDaSQt
STRIPE_SECRET_KEY=sk_test_51TWfTxDGcQIOgPxej8AvcfLMt6a7IEgZk3L34WLnOCNw2AAAyqORQtgJLjEaj3Ygm014ZAo3oByvDSdJVFwYLHmk0048mdLZH4
RESTRICTED_KEY=rk_test_51TWfTxDGcQIOgPxeGPSfA6ske0A6xPde23jfOJKbUfFOrEWl4bTIHv4MSOBwlQpravXk4mxKAjKdmkGb3asZqOVJ0048mdLZH4
# ── License Server (B2B SaaS) ──
LICENSE_PRICE_STARTER_CENTS=2900
LICENSE_PRICE_PRO_CENTS=5000
LICENSE_PRICE_ENTERPRISE_CENTS=15000
LICENSE_TRIAL_DAYS=14
LICENSE_NOTICE_PERIOD_DAYS=90
LICENSE_YEARLY_DISCOUNT_PCT=10
LICENSE_OFFLINE_GRACE_HOURS=72
# ── Agency / Reseller ──
AGENCY_DISCOUNT_MIN_PCT=0
AGENCY_DISCOUNT_MAX_PCT=20
AGENCY_DISCOUNT_DEFAULT_PCT=10
# ── Platform Domain ──
# The domain AOS runs on. Tenant instances get subdomains of this domain.
PLATFORM_DOMAIN=dfmpanel.eu
# Public URL of the AOS instance (used by license-server SDK + email links)
AOS_PUBLIC_URL=https://dfmpanel.eu
# ── Dokploy (tenant instance provisioning) ──
# Dokploy server URL + API key for managing tenant instances.
DOKPLOY_URL=https://cp.project-url.eu
DOKPLOY_API_KEY=CEIqJlWVtmSNgffNWywTJmEeuvUJBndinBzudretwiuzVWPxuvUNmoQaHUwRwUBy
# The Dokploy server ID to deploy to (default "default" if not set)
# DOKPLOY_SERVER_ID=default
# The Dokploy project to group tenant applications under
# DOKPLOY_PROJECT_ID=default
# The IP of the Dokploy server (used for Hetzner DNS A records)
# DOKPLOY_SERVER_IP=123.456.789.012
# ── Hetzner Cloud DNS ──
# DNS is managed via the Hetzner Cloud API (api.hetzner.cloud/v1/zones).
# The legacy dns.hetzner.com API was shut down in May 2026.
HETZNER_DNS_TOKEN=JhZMOBTMeWvXz91KVPxRh0U4UMFqkSNCMHJKiQS9kUjHIwCkWCc8ViZTm64MyaOp
# Zone ID of dfmpanel.eu (found via: GET https://api.hetzner.cloud/v1/zones)
HETZNER_ZONE_ID=1669672
# If true, a single *.dfmpanel.eu wildcard A record handles all subdomains.
# If false, a per-instance A record is created/deleted with each instance.
USE_WILDCARD_DNS=false
# ── Dokploy Server ──
# IP of the Dokploy server (A record target for instance subdomains).
# Found from the existing @ and www A records of dfmpanel.eu.
DOKPLOY_SERVER_IP=92.206.22.59
# ── Cron Job ──
# Shared secret for the cleanup cron job (POST /api/aos/instances/cleanup)
# The cron job (Dokploy cron or GitHub Action) must send this as:
# Authorization: Bearer <CRON_SECRET>
# CRON_SECRET=your-cron-secret
# ── Instance Defaults ──
# Default Git repo + branch for new tenant instances
INSTANCE_GIT_REPO=https://github.com/cetinmustafa83/restov1
INSTANCE_GIT_BRANCH=main
# Demo instance duration in days
INSTANCE_DEMO_DAYS=14
# Grace period after demo expiry or subscription cancellation (days)
INSTANCE_GRACE_DAYS=7
# ── Graphify (tenant codebase knowledge graph) ──
# Graphify MCP HTTP service (Docker container). When configured, new tenant
# instances trigger a background graph build, and the support ticket AI
# queries the codebase before generating a summary.
# Run: docker run -p 8080:8080 -v ./data/graphify:/data graphify serve
# --transport http --host 0.0.0.0 --api-key <secret>
# GRAPHIFY_URL=http://localhost:8080
# GRAPHIFY_API_KEY=your-graphify-api-key
+28
View File
@@ -0,0 +1,28 @@
name: AOS Cleanup Cron
on:
schedule:
# Run daily at 03:00 UTC (05:00 Berlin time)
- cron: '0 3 * * *'
workflow_dispatch: # Allow manual trigger
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Trigger instance cleanup
run: |
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
"${{ secrets.AOS_URL || 'https://dfmpanel.eu' }}/api/aos/instances/cleanup" \
-H "Authorization: Bearer ${{ secrets.CRON_SECRET }}" \
-H "Content-Type: application/json" \
--max-time 300)
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
echo "HTTP $HTTP_CODE"
echo "Response: $BODY"
if [ "$HTTP_CODE" != "200" ]; then
echo "::warning::Cleanup returned HTTP $HTTP_CODE"
exit 1
fi
echo "::notice::Cleanup completed successfully"
+3
View File
@@ -59,3 +59,6 @@ aos-verify*.sh
.dev.pid .dev.pid
.zscripts/dev.pid .zscripts/dev.pid
db/backups/ db/backups/
.env
tool-results/
upload/
Executable → Regular
+9
View File
@@ -43,6 +43,7 @@
"@reactuses/core": "^6.0.5", "@reactuses/core": "^6.0.5",
"@tanstack/react-query": "^5.82.0", "@tanstack/react-query": "^5.82.0",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"@types/nodemailer": "^8.0.2",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
@@ -57,6 +58,7 @@
"next-auth": "^4.24.11", "next-auth": "^4.24.11",
"next-intl": "^4.3.4", "next-intl": "^4.3.4",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nodemailer": "^10.2.1",
"prisma": "^6.11.1", "prisma": "^6.11.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-day-picker": "^9.8.0", "react-day-picker": "^9.8.0",
@@ -68,6 +70,7 @@
"recharts": "^2.15.4", "recharts": "^2.15.4",
"sharp": "^0.34.3", "sharp": "^0.34.3",
"sonner": "^2.0.6", "sonner": "^2.0.6",
"stripe": "^23.0.1",
"tailwind-merge": "^3.7.0", "tailwind-merge": "^3.7.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"uuid": "^11.1.0", "uuid": "^11.1.0",
@@ -720,6 +723,8 @@
"@types/node": ["@types/node@25.0.9", "https://registry.npmjs.com/@types/node/-/node-25.0.9.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="], "@types/node": ["@types/node@25.0.9", "https://registry.npmjs.com/@types/node/-/node-25.0.9.tgz", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="],
"@types/nodemailer": ["@types/nodemailer@8.0.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-c7M5ox8p0nEOfbJ2E9Qcmt8/QCu/VzsiAhzBiZbvky2PhKZDHpKB3sQHBM5MEZNkCfBOaS6S9//AGPRTNB7IaA=="],
"@types/react": ["@types/react@19.2.8", "https://registry.npmjs.com/@types/react/-/react-19.2.8.tgz", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg=="], "@types/react": ["@types/react@19.2.8", "https://registry.npmjs.com/@types/react/-/react-19.2.8.tgz", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg=="],
"@types/react-dom": ["@types/react-dom@19.2.3", "https://registry.npmjs.com/@types/react-dom/-/react-dom-19.2.3.tgz", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], "@types/react-dom": ["@types/react-dom@19.2.3", "https://registry.npmjs.com/@types/react-dom/-/react-dom-19.2.3.tgz", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
@@ -1520,6 +1525,8 @@
"node-releases": ["node-releases@2.0.27", "https://registry.npmjs.com/node-releases/-/node-releases-2.0.27.tgz", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], "node-releases": ["node-releases@2.0.27", "https://registry.npmjs.com/node-releases/-/node-releases-2.0.27.tgz", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
"nodemailer": ["nodemailer@10.2.1", "", {}, "sha512-ZrDNsPFoDMwefNs7sJwrYiEJ/CG4ClJWDZv05iNJsEBWa8GRDry1QJHTJxsuTAY9eDDKjX4k+q3SxslXJOao7w=="],
"nypm": ["nypm@0.6.2", "https://registry.npmjs.com/nypm/-/nypm-0.6.2.tgz", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="], "nypm": ["nypm@0.6.2", "https://registry.npmjs.com/nypm/-/nypm-0.6.2.tgz", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="],
"oauth": ["oauth@0.9.15", "https://registry.npmjs.com/oauth/-/oauth-0.9.15.tgz", {}, "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="], "oauth": ["oauth@0.9.15", "https://registry.npmjs.com/oauth/-/oauth-0.9.15.tgz", {}, "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="],
@@ -1756,6 +1763,8 @@
"strip-json-comments": ["strip-json-comments@3.1.1", "https://registry.npmjs.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], "strip-json-comments": ["strip-json-comments@3.1.1", "https://registry.npmjs.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"stripe": ["stripe@23.0.1", "", { "peerDependencies": { "@types/node": ">=20" }, "optionalPeers": ["@types/node"] }, "sha512-VFLs9IAzSZ8GIm6/vqhjqOL0fbYrSNYCpgZ3LS3YkSi/i5RnyMpu/Hf9YxPTOCYwc3mZKU3IJvuvKffQH2NLMg=="],
"style-mod": ["style-mod@4.1.3", "https://registry.npmjs.com/style-mod/-/style-mod-4.1.3.tgz", {}, "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ=="], "style-mod": ["style-mod@4.1.3", "https://registry.npmjs.com/style-mod/-/style-mod-4.1.3.tgz", {}, "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ=="],
"style-to-js": ["style-to-js@1.1.21", "https://registry.npmjs.com/style-to-js/-/style-to-js-1.1.21.tgz", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], "style-to-js": ["style-to-js@1.1.21", "https://registry.npmjs.com/style-to-js/-/style-to-js-1.1.21.tgz", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="],
+4 -1
View File
@@ -9,7 +9,7 @@
"scripts": { "scripts": {
"dev": "next dev -p 3000", "dev": "next dev -p 3000",
"dev:log": "next dev -p 3000 2>&1 | tee dev.log", "dev:log": "next dev -p 3000 2>&1 | tee dev.log",
"build": "prisma generate && next build --webpack && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/", "build": "prisma generate && next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/",
"start": "NODE_ENV=production bun .next/standalone/server.js 2>&1 | tee server.log", "start": "NODE_ENV=production bun .next/standalone/server.js 2>&1 | tee server.log",
"lint": "eslint .", "lint": "eslint .",
"db:push": "prisma db push --accept-data-loss", "db:push": "prisma db push --accept-data-loss",
@@ -57,6 +57,7 @@
"@reactuses/core": "^6.0.5", "@reactuses/core": "^6.0.5",
"@tanstack/react-query": "^5.82.0", "@tanstack/react-query": "^5.82.0",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"@types/nodemailer": "^8.0.2",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
@@ -71,6 +72,7 @@
"next-auth": "^4.24.11", "next-auth": "^4.24.11",
"next-intl": "^4.3.4", "next-intl": "^4.3.4",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nodemailer": "^10.2.1",
"prisma": "^6.11.1", "prisma": "^6.11.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-day-picker": "^9.8.0", "react-day-picker": "^9.8.0",
@@ -82,6 +84,7 @@
"recharts": "^2.15.4", "recharts": "^2.15.4",
"sharp": "^0.34.3", "sharp": "^0.34.3",
"sonner": "^2.0.6", "sonner": "^2.0.6",
"stripe": "^23.0.1",
"tailwind-merge": "^3.7.0", "tailwind-merge": "^3.7.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"uuid": "^11.1.0", "uuid": "^11.1.0",
+10 -4
View File
@@ -72,16 +72,22 @@ export async function PATCH(req: Request, { params }: { params: Promise<{ id: st
}, },
}) })
// TODO (production): send email to company.email with subject // Send approval email
// "Ihre Reseller-Bewerbung wurde genehmigt — {discountPct}% Rabatt" const { sendAgencyApprovedEmail } = await import('@/lib/email')
// containing the discount and a link to the agency portal. if (application.company.email) {
await sendAgencyApprovedEmail({
to: application.company.email,
companyName: application.company.name,
discountPct,
})
}
return NextResponse.json({ return NextResponse.json({
ok: true, ok: true,
status: 'approved', status: 'approved',
discountPct, discountPct,
email: application.company.email, email: application.company.email,
message: `Genehmigt mit ${discountPct}% Rabatt. E-Mail an ${application.company.email ?? '(keine E-Mail hinterlegt)'} würde versendet.`, message: `Genehmigt mit ${discountPct}% Rabatt.${application.company.email ? ` E-Mail an ${application.company.email} versendet.` : ' Keine E-Mail hinterlegt.'}`,
}) })
} catch (err) { } catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error' const msg = err instanceof Error ? err.message : 'internal server error'
@@ -60,6 +60,16 @@ export async function PATCH(req: Request, { params }: { params: Promise<{ id: st
}, },
}) })
// Send rejection email
const { sendAgencyRejectedEmail } = await import('@/lib/email')
if (application.company.email) {
await sendAgencyRejectedEmail({
to: application.company.email,
companyName: application.company.name,
reason,
})
}
return NextResponse.json({ ok: true, status: 'rejected', reason }) return NextResponse.json({ ok: true, status: 'rejected', reason })
} catch (err) { } catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error' const msg = err instanceof Error ? err.message : 'internal server error'
@@ -0,0 +1,289 @@
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { z } from 'zod'
import { createHetznerDnsClientFromEnv } from '@/lib/hetzner-dns'
import { createDokployClientFromEnv } from '@/lib/dokploy'
export const dynamic = 'force-dynamic'
const postSchema = z.object({
domain: z.string().min(3).max(253).regex(/^[a-zA-Z0-9.-]+$/, 'invalid domain'),
})
// POST /api/aos/instances/[id]/custom-domain
// Step 1: Client requests to attach a custom domain.
// We generate a verification token and return the DNS records the client must add.
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
try {
const { id } = await params
const parsed = postSchema.safeParse(await req.json())
if (!parsed.success) {
return NextResponse.json({ error: 'invalid domain', details: parsed.error.flatten() }, { status: 400 })
}
const domain = parsed.data.domain.toLowerCase()
// Validate domain format
if (domain.startsWith('-') || domain.endsWith('-') || domain.includes('..')) {
return NextResponse.json({ error: 'invalid domain format' }, { status: 400 })
}
// Reject IP addresses, wildcard domains, and platform-owned domains
if (/^\d+\.\d+\.\d+\.\d+$/.test(domain)) {
return NextResponse.json({ error: 'IP addresses not allowed' }, { status: 400 })
}
if (domain.startsWith('*.')) {
return NextResponse.json({ error: 'wildcard domains not allowed' }, { status: 400 })
}
const platformDomain = process.env.PLATFORM_DOMAIN ?? 'dfmpanel.eu'
if (domain === platformDomain || domain.endsWith(`.${platformDomain}`)) {
return NextResponse.json({ error: 'platform-owned domains not allowed' }, { status: 400 })
}
const instance = await db.instance.findUnique({ where: { id } })
if (!instance) {
return NextResponse.json({ error: 'instance not found' }, { status: 404 })
}
if (!['active', 'demo_active'].includes(instance.status)) {
return NextResponse.json({ error: `cannot attach domain to instance in status ${instance.status}` }, { status: 400 })
}
// Check that the domain isn't already claimed by another instance
const existing = await db.instance.findFirst({
where: { customDomain: domain, id: { not: id } },
})
if (existing) {
return NextResponse.json({ error: 'domain already claimed by another instance' }, { status: 409 })
}
// Generate verification token
const crypto = await import('crypto')
const token = `dfm-verify-${crypto.randomBytes(16).toString('hex')}`
await db.instance.update({
where: { id },
data: {
customDomain: domain,
domainVerificationToken: token,
domainVerifiedAt: null,
},
})
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.requested',
step: 'domain',
result: 'ok',
details: JSON.stringify({ domain, token }),
},
})
// Return the DNS records the client must add
return NextResponse.json({
ok: true,
domain,
verificationToken: token,
dnsRecords: [
{
type: 'TXT',
name: `_dfm-verify.${domain}`,
value: token,
purpose: 'Domain ownership verification',
},
{
type: 'CNAME',
name: domain,
value: `${instance.subdomain}.${platformDomain}`,
purpose: 'Point domain to the instance',
},
],
instructions: [
`1. Füge einen TXT-Record hinzu: _dfm-verify.${domain} = ${token}`,
`2. Füge einen CNAME-Record hinzu: ${domain} → ${instance.subdomain}.${platformDomain}`,
`3. Warte 5-15 Minuten bis die DNS-Änderungen wirksam sind.`,
`4. Rufe dann die Verifizierung auf: PATCH /api/aos/instances/${id}/custom-domain`,
],
})
} catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error'
return NextResponse.json({ error: msg }, { status: 500 })
}
}
// PATCH /api/aos/instances/[id]/custom-domain
// Step 2: Verify the DNS records and attach the domain in Dokploy.
export async function PATCH(req: Request, { params }: { params: Promise<{ id: string }> }) {
try {
const { id } = await params
const instance = await db.instance.findUnique({ where: { id } })
if (!instance) {
return NextResponse.json({ error: 'instance not found' }, { status: 404 })
}
if (!instance.customDomain || !instance.domainVerificationToken) {
return NextResponse.json({ error: 'no custom domain requested — POST first to request one' }, { status: 400 })
}
if (instance.domainVerifiedAt) {
return NextResponse.json({ error: 'domain already verified' }, { status: 409 })
}
const dns = createHetznerDnsClientFromEnv()
if (!dns) {
return NextResponse.json({ error: 'DNS client not configured' }, { status: 503 })
}
// 1. Verify TXT record
const txtResult = await dns.verifyTxtRecord(
`_dfm-verify.${instance.customDomain}`,
instance.domainVerificationToken
)
if (!txtResult.verified) {
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.verify.txt.failed',
step: 'domain',
result: 'error',
details: JSON.stringify({ error: txtResult.error }),
},
})
return NextResponse.json({
ok: false,
verified: false,
step: 'txt',
error: txtResult.error,
message: 'TXT-Record noch nicht gefunden. Warte einige Minuten und versuche es erneut.',
}, { status: 202 })
}
// 2. Verify CNAME record
const platformDomain = process.env.PLATFORM_DOMAIN ?? 'dfmpanel.eu'
const expectedTarget = `${instance.subdomain}.${platformDomain}`
const cnameResult = await dns.verifyCustomDomainCname(instance.customDomain, expectedTarget)
if (!cnameResult.verified) {
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.verify.cname.failed',
step: 'domain',
result: 'error',
details: JSON.stringify({ error: cnameResult.error, found: cnameResult.found }),
},
})
return NextResponse.json({
ok: false,
verified: false,
step: 'cname',
error: cnameResult.error,
message: `CNAME zeigt auf "${cnameResult.found ?? 'nichts'}", erwartet: "${expectedTarget}"`,
}, { status: 202 })
}
// 3. Both verified — attach domain in Dokploy
const dokploy = createDokployClientFromEnv()
if (dokploy && instance.dokployAppId) {
try {
await dokploy.createDomain({
applicationId: instance.dokployAppId,
hostName: instance.customDomain,
port: 3000,
https: true,
})
} catch (e) {
// Non-fatal — domain verification still succeeded, Dokploy attach can retry
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.dokploy.attach.error',
step: 'domain',
result: 'error',
details: JSON.stringify({ error: e instanceof Error ? e.message : 'unknown' }),
},
})
}
}
// 4. Mark verified
await db.instance.update({
where: { id },
data: { domainVerifiedAt: new Date() },
})
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.verified',
step: 'domain',
result: 'ok',
details: JSON.stringify({ domain: instance.customDomain }),
},
})
await db.auditLog.create({
data: {
actor: 'admin:ui',
action: 'instance.domain.verified',
entity: 'Instance',
entityId: id,
after: JSON.stringify({ domain: instance.customDomain }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
return NextResponse.json({
ok: true,
verified: true,
domain: instance.customDomain,
message: `Domain ${instance.customDomain} verifiziert und in Dokploy hinterlegt.`,
})
} catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error'
return NextResponse.json({ error: msg }, { status: 500 })
}
}
// DELETE /api/aos/instances/[id]/custom-domain
// Remove the custom domain (keeps the platform subdomain active).
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
try {
const { id } = await params
const instance = await db.instance.findUnique({ where: { id } })
if (!instance) {
return NextResponse.json({ error: 'instance not found' }, { status: 404 })
}
if (!instance.customDomain) {
return NextResponse.json({ error: 'no custom domain set' }, { status: 400 })
}
// Remove from Dokploy (best-effort)
const dokploy = createDokployClientFromEnv()
if (dokploy && instance.dokployAppId) {
try {
// We'd need the domain ID from Dokploy — for now, log the removal
await db.instanceEvent.create({
data: {
instanceId: id,
type: 'domain.removed',
step: 'domain',
result: 'ok',
details: JSON.stringify({ domain: instance.customDomain }),
},
})
} catch (e) {
// Non-fatal
}
}
await db.instance.update({
where: { id },
data: {
customDomain: null,
domainVerificationToken: null,
domainVerifiedAt: null,
},
})
return NextResponse.json({ ok: true, message: 'Custom domain removed' })
} catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error'
return NextResponse.json({ error: msg }, { status: 500 })
}
}
+1 -2
View File
@@ -184,8 +184,7 @@ export async function DELETE(_req: Request, { params }: { params: Promise<{ id:
try { try {
const result = await dokploy.teardownInstance({ const result = await dokploy.teardownInstance({
dokployAppId: instance.dokployAppId ?? undefined, dokployAppId: instance.dokployAppId ?? undefined,
dokployDbId: instance.dokployDbId ?? undefined, dokployDomainId: meta.dokployDomainId,
dnsDomainId: meta.dokployDomainId,
}) })
steps.push(...result.steps) steps.push(...result.steps)
await db.instanceEvent.create({ await db.instanceEvent.create({
+1 -2
View File
@@ -88,8 +88,7 @@ export async function POST(req: Request) {
try { try {
const r = await dokploy.teardownInstance({ const r = await dokploy.teardownInstance({
dokployAppId: inst.dokployAppId ?? undefined, dokployAppId: inst.dokployAppId ?? undefined,
dokployDbId: inst.dokployDbId ?? undefined, dokployDomainId: meta.dokployDomainId,
dnsDomainId: meta.dokployDomainId,
}) })
steps.push(...r.steps) steps.push(...r.steps)
} catch (e) { } catch (e) {
+31 -8
View File
@@ -158,7 +158,7 @@ export async function POST(req: Request) {
gitRepo, gitRepo,
gitBranch, gitBranch,
envVars: instanceEnv, envVars: instanceEnv,
databaseName: `${product}_${subdomain}`.replace(/-/g, '_').slice(0, 40), gitProvider: gitRepo.includes('github.com') ? 'github' : 'gitea',
cpuLimit: plan === 'enterprise' ? '2' : plan === 'pro' ? '1' : '0.5', cpuLimit: plan === 'enterprise' ? '2' : plan === 'pro' ? '1' : '0.5',
memoryLimit: plan === 'enterprise' ? '2048m' : plan === 'pro' ? '1024m' : '512m', memoryLimit: plan === 'enterprise' ? '2048m' : plan === 'pro' ? '1024m' : '512m',
} }
@@ -183,8 +183,7 @@ export async function POST(req: Request) {
result: 'ok', result: 'ok',
details: JSON.stringify({ details: JSON.stringify({
appId: result.app.applicationId, appId: result.app.applicationId,
dbId: result.database?.databaseId, domainId: result.domain?.domainId,
domainId: result.domain.domainId,
url: result.url, url: result.url,
}), }),
}, },
@@ -227,15 +226,11 @@ export async function POST(req: Request) {
data: { data: {
status: isDemo ? 'demo_active' : 'active', status: isDemo ? 'demo_active' : 'active',
dokployAppId: result.app.applicationId, dokployAppId: result.app.applicationId,
dokployDbId: result.database?.databaseId ?? null,
dokployDbName: result.database?.database ?? null,
dokployDbUser: result.database?.username ?? null,
dokployDbPassword: result.database?.password ?? null,
dnsRecordId, dnsRecordId,
metadata: JSON.stringify({ metadata: JSON.stringify({
gitRepo, gitRepo,
gitBranch, gitBranch,
dokployDomainId: result.domain.domainId, dokployDomainId: result.domain?.domainId ?? null,
url: result.url, url: result.url,
provisionedAt: now.toISOString(), provisionedAt: now.toISOString(),
}), }),
@@ -258,6 +253,20 @@ export async function POST(req: Request) {
}, },
}) })
// --- Generate admin login token (one-time, 7-day expiry) ---
// This token allows the client to access their instance admin panel
// without separate credentials. Sent via email (if SMTP configured).
const crypto = await import('crypto')
const adminToken = `admin-${crypto.randomBytes(24).toString('hex')}`
const adminTokenExpires = new Date(Date.now() + 7 * 86400000)
await db.instance.update({
where: { id: instance.id },
data: {
adminLoginToken: adminToken,
adminLoginExpiresAt: adminTokenExpires,
},
})
// --- Graphify: trigger background graph build --- // --- Graphify: trigger background graph build ---
// Builds a knowledge graph from the instance's Git repo so the support // Builds a knowledge graph from the instance's Git repo so the support
// ticket AI can query the codebase later. Fire-and-forget: we don't // ticket AI can query the codebase later. Fire-and-forget: we don't
@@ -300,12 +309,26 @@ export async function POST(req: Request) {
}, },
}) })
// Send instance ready email with admin login link
const { sendEmail } = await import('@/lib/email')
if (company.email) {
const adminLoginUrl = `${result.url}/?admin_token=${adminToken}`
sendEmail({
to: company.email,
subject: `Ihre ${product}-Instanz ist bereit — ${result.url}`,
text: `Guten Tag,\n\nIhre Instanz wurde erfolgreich bereitgestellt.\n\nURL: ${result.url}\nAdmin-Login: ${adminLoginUrl}\n${isDemo ? `Demo-Laufzeit: 14 Tage (endet am ${new Date(instance.demoExpiresAt!).toLocaleDateString('de-DE')})` : ''}\n\nMit freundlichen Grüßen\nDFM Solutions`,
html: `<p>Guten Tag,</p><p>Ihre <strong>${product}</strong>-Instanz wurde erfolgreich bereitgestellt.</p><p><strong>URL:</strong> <a href="${result.url}">${result.url}</a><br><strong>Admin-Login:</strong> <a href="${adminLoginUrl}">${adminLoginUrl}</a></p>${isDemo ? `<p><strong>Demo-Laufzeit:</strong> 14 Tage (endet am ${new Date(instance.demoExpiresAt!).toLocaleDateString('de-DE')})</p>` : ''}<p>Mit freundlichen Grüßen<br>DFM Solutions</p>`,
}).catch(() => {})
}
return NextResponse.json({ return NextResponse.json({
instanceId: instance.id, instanceId: instance.id,
subdomain, subdomain,
url: result.url, url: result.url,
status: isDemo ? 'demo_active' : 'active', status: isDemo ? 'demo_active' : 'active',
demoExpiresAt: instance.demoExpiresAt, demoExpiresAt: instance.demoExpiresAt,
adminLoginToken: adminToken,
adminLoginUrl: `${result.url}/?admin_token=${adminToken}`,
}, { status: 201 }) }, { status: 201 })
} catch (provErr) { } catch (provErr) {
// Provisioning failed — mark as failed, keep the record for retry // Provisioning failed — mark as failed, keep the record for retry
+12
View File
@@ -304,6 +304,18 @@ export async function POST(req: Request) {
}, },
}) })
// Send license key email to the customer
const { sendLicenseKeyEmail } = await import('@/lib/email')
if (company.email && !parentId) {
// Only send for core licenses (not modules)
sendLicenseKeyEmail({
to: company.email,
licenseKey: key,
product,
plan,
}).catch(() => {}) // fire-and-forget, don't block response
}
return NextResponse.json({ license, pricing: pricing.breakdown }, { status: 201 }) return NextResponse.json({ license, pricing: pricing.breakdown }, { status: 201 })
} catch (err) { } catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error' const msg = err instanceof Error ? err.message : 'internal server error'
+6 -4
View File
@@ -206,18 +206,20 @@ export async function POST(req: Request) {
const existingTokens = await db.apiToken.count() const existingTokens = await db.apiToken.count()
if (existingTokens === 0) { if (existingTokens === 0) {
const adminScopes = ['mcp:read', 'mcp:write', 'crm.company:read', 'crm.deal:read', 'finance.invoice:read', 'leads:read', 'leads:write', 'support:read', 'support:write', 'licenses.license:read', 'licenses.license:write'] const adminScopes = ['mcp:read', 'mcp:write', 'crm.company:read', 'crm.deal:read', 'finance.invoice:read', 'leads:read', 'leads:write', 'support:read', 'support:write', 'licenses.license:read', 'licenses.license:write']
const token = 'aos_admin_seed_token_for_claude_code_2026' // Use MCP_API_TOKEN env var if set, otherwise generate a random one
const hash = crypto.createHash('sha256').update(token).digest('hex') const tokenValue = process.env.MCP_API_TOKEN || ('aos_' + crypto.randomUUID())
const hash = crypto.createHash('sha256').update(tokenValue).digest('hex')
await db.apiToken.create({ await db.apiToken.create({
data: { data: {
name: 'Claude Code Admin (seeded)', name: 'MCP Admin Token (seeded)',
tokenHash: hash, tokenHash: hash,
tokenPrefix: token.slice(0, 12) + '…', tokenPrefix: tokenValue.slice(0, 12) + '…',
scopes: adminScopes.join(','), scopes: adminScopes.join(','),
expiresAt: null, expiresAt: null,
}, },
}) })
stats.apiTokens = 1 stats.apiTokens = 1
stats.mcpToken = tokenValue === process.env.MCP_API_TOKEN ? '(from env)' : tokenValue
} else { } else {
stats.apiTokens = 0 stats.apiTokens = 0
} }
+62
View File
@@ -0,0 +1,62 @@
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { createCheckoutSession } from '@/lib/stripe'
export const dynamic = 'force-dynamic'
// POST /api/aos/stripe/checkout
// Creates a Stripe Checkout session for a license subscription.
// Body: { licenseId: string }
export async function POST(req: Request) {
try {
const { licenseId } = await req.json()
if (!licenseId) {
return NextResponse.json({ error: 'licenseId required' }, { status: 400 })
}
const license = await db.license.findUnique({
where: { id: licenseId },
include: { company: true },
})
if (!license) {
return NextResponse.json({ error: 'license not found' }, { status: 404 })
}
if (license.parentId) {
return NextResponse.json({ error: 'checkout for module licenses not supported — pay for the core license' }, { status: 400 })
}
if (license.netPriceCents <= 0) {
return NextResponse.json({ error: 'this license has no price (free)' }, { status: 400 })
}
const result = await createCheckoutSession({
licenseId: license.id,
licenseKey: license.key,
product: license.product,
plan: license.plan,
billingCycle: license.billingCycle as 'monthly' | 'yearly',
netPriceCents: license.netPriceCents,
customerEmail: license.company.email ?? undefined,
})
if ('error' in result) {
return NextResponse.json({ error: result.error }, { status: 502 })
}
// Audit
await db.auditLog.create({
data: {
actor: 'client:checkout',
action: 'stripe.checkout.created',
entity: 'License',
entityId: license.id,
after: JSON.stringify({ plan: license.plan, cycle: license.billingCycle, netPriceCents: license.netPriceCents }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
return NextResponse.json({ url: result.url })
} catch (err) {
const msg = err instanceof Error ? err.message : 'internal server error'
return NextResponse.json({ error: msg }, { status: 500 })
}
}
+178
View File
@@ -0,0 +1,178 @@
import { NextResponse } from 'next/server'
import { db } from '@/lib/db'
import { constructWebhookEvent } from '@/lib/stripe'
import type Stripe from 'stripe'
export const dynamic = 'force-dynamic'
export const maxDuration = 30
// POST /api/aos/stripe/webhook
// Handles Stripe webhook events:
// - checkout.session.completed → link Stripe customer + subscription to license
// - invoice.paid → activate license (remove trial, set to active)
// - customer.subscription.deleted → cancel license (grace → delete)
// - invoice.payment_failed → suspend license after dunning
export async function POST(req: Request) {
const body = await req.text()
const signature = req.headers.get('stripe-signature') ?? ''
const event = constructWebhookEvent(body, signature)
if (!event) {
return NextResponse.json({ error: 'invalid signature' }, { status: 400 })
}
try {
switch (event.type) {
case 'checkout.session.completed': {
const session = event.data.object as Stripe.Checkout.Session
const licenseId = session.metadata?.licenseId
if (!licenseId) break
// Link Stripe customer + subscription to the license
await db.license.update({
where: { id: licenseId },
data: {
stripeCustomerId: session.customer as string,
stripeSubscriptionId: session.subscription as string,
},
})
await db.auditLog.create({
data: {
actor: 'stripe:webhook',
action: 'stripe.checkout.completed',
entity: 'License',
entityId: licenseId,
after: JSON.stringify({ customerId: session.customer, subscriptionId: session.subscription }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
break
}
case 'invoice.paid': {
const invoice = event.data.object as Stripe.Invoice
const subscriptionId = (invoice as Stripe.Invoice & { subscription?: string }).subscription
if (!subscriptionId) break
// Find license by Stripe subscription ID and activate it
const license = await db.license.findFirst({
where: { stripeSubscriptionId: subscriptionId },
})
if (!license) break
// If license was in trial, move to active (paid subscription started)
if (license.trialEndsAt && new Date(license.trialEndsAt) > new Date()) {
await db.license.update({
where: { id: license.id },
data: {
status: 'active',
trialEndsAt: null,
subscriptionStartsAt: new Date(),
},
})
}
await db.auditLog.create({
data: {
actor: 'stripe:webhook',
action: 'stripe.invoice.paid',
entity: 'License',
entityId: license.id,
after: JSON.stringify({ invoiceId: invoice.id, amount: invoice.amount_paid }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
break
}
case 'customer.subscription.deleted': {
const subscription = event.data.object as Stripe.Subscription
const license = await db.license.findFirst({
where: { stripeSubscriptionId: subscription.id },
})
if (!license) break
// Subscription cancelled → license goes to grace, then deletion
// (handled by the cleanup cron job)
const now = new Date()
await db.license.update({
where: { id: license.id },
data: {
status: 'cancelled',
cancelledAt: now,
cancellationEffectiveAt: new Date(now.getTime() + 7 * 86400000), // 7-day grace
cancellationReason: 'Stripe subscription deleted',
},
})
// If there's a linked instance, schedule it for deletion too
const instance = await db.instance.findFirst({
where: { licenseId: license.id, status: { notIn: ['deleted', 'deleting'] } },
})
if (instance) {
await db.instance.update({
where: { id: instance.id },
data: {
status: 'grace',
graceEndsAt: new Date(now.getTime() + 7 * 86400000),
},
})
}
await db.auditLog.create({
data: {
actor: 'stripe:webhook',
action: 'stripe.subscription.deleted',
entity: 'License',
entityId: license.id,
after: JSON.stringify({ subscriptionId: subscription.id, graceEndsAt: now.getTime() + 7 * 86400000 }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
break
}
case 'invoice.payment_failed': {
const invoice = event.data.object as Stripe.Invoice
const subscriptionId = (invoice as Stripe.Invoice & { subscription?: string }).subscription
if (!subscriptionId) break
const license = await db.license.findFirst({
where: { stripeSubscriptionId: subscriptionId },
})
if (!license) break
// Payment failed → suspend license (dunning)
await db.license.update({
where: { id: license.id },
data: {
status: 'suspended',
suspendReason: 'Stripe payment failed',
suspendedAt: new Date(),
},
})
await db.auditLog.create({
data: {
actor: 'stripe:webhook',
action: 'stripe.payment.failed',
entity: 'License',
entityId: license.id,
after: JSON.stringify({ invoiceId: invoice.id, attempt: invoice.attempt_count }),
hash: 'sha256:' + Math.random().toString(36).slice(2),
},
})
break
}
default:
// Unhandled event type — log but don't fail
break
}
return NextResponse.json({ received: true })
} catch (err) {
const msg = err instanceof Error ? err.message : 'webhook handler failed'
return NextResponse.json({ error: msg }, { status: 500 })
}
}
+64
View File
@@ -0,0 +1,64 @@
import { NextResponse } from 'next/server'
import { z } from 'zod'
export const dynamic = 'force-dynamic'
const schema = z.object({
password: z.string().min(1),
redirect: z.string().optional(),
})
// POST /api/auth/login
// Simple password-based auth. Password is set via ADMIN_PASSWORD env var.
// Returns a session cookie (HMAC-signed, 7-day expiry).
export async function POST(req: Request) {
try {
const parsed = schema.safeParse(await req.json())
if (!parsed.success) {
return NextResponse.json({ error: 'invalid request' }, { status: 400 })
}
const { password, redirect } = parsed.data
const adminPassword = process.env.ADMIN_PASSWORD
if (!adminPassword) {
return NextResponse.json(
{ error: 'ADMIN_PASSWORD env not configured. Set it in Dokploy environment variables.' },
{ status: 503 }
)
}
if (password !== adminPassword) {
return NextResponse.json({ error: 'Falsches Passwort' }, { status: 401 })
}
// Create session token: base64(payload).hmac
const crypto = await import('crypto')
const payload = {
sub: 'admin',
iat: Date.now(),
exp: Date.now() + 7 * 24 * 3600 * 1000, // 7 days
}
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString('base64url')
const key = process.env.AUTH_SECRET || adminPassword
const signature = crypto
.createHmac('sha256', key)
.update(payloadB64)
.digest('base64url')
const token = `${payloadB64}.${signature}`
const res = NextResponse.json({
ok: true,
redirect: redirect || '/',
})
res.cookies.set('aos-session', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
path: '/',
maxAge: 7 * 24 * 3600, // 7 days
})
return res
} catch {
return NextResponse.json({ error: 'login failed' }, { status: 500 })
}
}
+10
View File
@@ -0,0 +1,10 @@
import { NextResponse } from 'next/server'
export const dynamic = 'force-dynamic'
// POST /api/auth/logout
export async function POST() {
const res = NextResponse.json({ ok: true })
res.cookies.delete('aos-session')
return res
}
+92
View File
@@ -0,0 +1,92 @@
'use client'
import { Suspense, useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Loader2, Lock } from 'lucide-react'
function LoginForm() {
const router = useRouter()
const searchParams = useSearchParams()
const redirect = searchParams.get('redirect') || '/'
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!password) return
setLoading(true)
setError('')
try {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ password, redirect }),
})
const data = await res.json()
if (!res.ok) {
setError(data.error || 'Login fehlgeschlagen')
return
}
router.push(data.redirect || '/')
router.refresh()
} catch {
setError('Netzwerkfehler')
} finally {
setLoading(false)
}
}
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="password">Passwort</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Admin-Passwort eingeben"
autoFocus
autoComplete="current-password"
/>
</div>
{error && (
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
)}
<Button type="submit" className="w-full gap-2" disabled={loading || !password}>
{loading && <Loader2 className="size-4 animate-spin" />}
Anmelden
</Button>
</form>
)
}
export default function LoginPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-background p-4">
<div className="w-full max-w-sm space-y-6">
<div className="text-center space-y-2">
<div className="mx-auto flex size-14 items-center justify-center rounded-xl bg-foreground text-background">
<Lock className="size-7" />
</div>
<h1 className="text-2xl font-semibold tracking-tight">AOS Login</h1>
<p className="text-sm text-muted-foreground">
Agency Operating System — dfmpanel.eu
</p>
</div>
<Suspense fallback={<div className="text-center text-sm text-muted-foreground">Laden…</div>}>
<LoginForm />
</Suspense>
<p className="text-center text-xs text-muted-foreground">
Geschützter Bereich — nur für autorisierte Benutzer.
</p>
</div>
</div>
)
}
+2
View File
@@ -19,6 +19,7 @@ import { TimesheetView } from './views/timesheet'
import { SupportView } from './views/support' import { SupportView } from './views/support'
import { LicensesView } from './views/licenses' import { LicensesView } from './views/licenses'
import { AgencyView } from './views/agency' import { AgencyView } from './views/agency'
import { ResellerPortalView } from './views/reseller-portal'
import { InstancesView } from './views/instances' import { InstancesView } from './views/instances'
import { ContractsView } from './views/contracts' import { ContractsView } from './views/contracts'
import { ExpensesView } from './views/expenses' import { ExpensesView } from './views/expenses'
@@ -97,6 +98,7 @@ export function AppShell() {
{view === 'support' && <SupportView />} {view === 'support' && <SupportView />}
{view === 'licenses' && <LicensesView />} {view === 'licenses' && <LicensesView />}
{view === 'agency' && <AgencyView />} {view === 'agency' && <AgencyView />}
{view === 'reseller_portal' && <ResellerPortalView />}
{view === 'instances' && <InstancesView />} {view === 'instances' && <InstancesView />}
{view === 'contracts' && <ContractsView />} {view === 'contracts' && <ContractsView />}
{view === 'expenses' && <ExpensesView />} {view === 'expenses' && <ExpensesView />}
+2
View File
@@ -27,6 +27,7 @@ import {
CalendarDays, CalendarDays,
Database, Database,
Server, Server,
Store,
} from 'lucide-react' } from 'lucide-react'
import { useAos, type ViewId } from '@/store/aos' import { useAos, type ViewId } from '@/store/aos'
import { import {
@@ -51,6 +52,7 @@ const VIEWS: { id: ViewId; label: string; icon: typeof LayoutDashboard; hint: st
{ id: 'support', label: 'Support', icon: LifeBuoy, hint: 'Tickets & SLA' }, { id: 'support', label: 'Support', icon: LifeBuoy, hint: 'Tickets & SLA' },
{ id: 'licenses', label: 'Lizenzen', icon: KeyRound, hint: 'Ausgestellt & Erneuerungen' }, { id: 'licenses', label: 'Lizenzen', icon: KeyRound, hint: 'Ausgestellt & Erneuerungen' },
{ id: 'agency', label: 'Reseller', icon: Users, hint: 'Reseller-Bewerbungen & Rabatte' }, { id: 'agency', label: 'Reseller', icon: Users, hint: 'Reseller-Bewerbungen & Rabatte' },
{ id: 'reseller_portal', label: 'Reseller-Portal', icon: Store, hint: 'Selbstbedienung: Kunden, Lizenzen, Tickets' },
{ id: 'instances', label: 'Instanzen', icon: Server, hint: 'Tenant-Instanzen & Provisioning' }, { id: 'instances', label: 'Instanzen', icon: Server, hint: 'Tenant-Instanzen & Provisioning' },
{ id: 'contracts', label: 'Verträge', icon: FileSignature, hint: 'Werkvertrag, AVV, NDA' }, { id: 'contracts', label: 'Verträge', icon: FileSignature, hint: 'Werkvertrag, AVV, NDA' },
{ id: 'expenses', label: 'Ausgaben', icon: Wallet, hint: 'Belastbar & DATEV' }, { id: 'expenses', label: 'Ausgaben', icon: Wallet, hint: 'Belastbar & DATEV' },
+250 -2
View File
@@ -37,10 +37,20 @@ import {
AlertTriangle, AlertTriangle,
Bell, Bell,
Info, Info,
CreditCard,
Plus,
Ban,
} from 'lucide-react' } from 'lucide-react'
import { toast } from 'sonner'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { formatEuro, formatDate, formatRelative, daysUntil } from '@/lib/format' import { formatEuro, formatDate, formatRelative, daysUntil } from '@/lib/format'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { toast } from 'sonner'
import { import {
Popover, Popover,
PopoverContent, PopoverContent,
@@ -94,6 +104,8 @@ interface PortalData {
licenses: { licenses: {
id: string; key: string; product: string; plan: string; status: string id: string; key: string; product: string; plan: string; status: string
validUntil: string | null; activations: { domain: string; environment: string }[] validUntil: string | null; activations: { domain: string; environment: string }[]
netPriceCents: number; billingCycle: string; parentId: string | null
trialEndsAt: string | null; noticePeriodDays: number; cancelledAt: string | null
}[] }[]
} }
@@ -503,6 +515,32 @@ function PortalApprovals({ data, refetch }: { data: PortalData; refetch: () => v
} }
function PortalInvoices({ data }: { data: PortalData }) { function PortalInvoices({ data }: { data: PortalData }) {
const [paying, setPaying] = useState<string | null>(null)
const companyId = data.company.id
const pay = async (licenseId: string) => {
setPaying(licenseId)
const t = toast.loading('Stripe Checkout wird vorbereitet…')
try {
const r = await fetch('/api/aos/stripe/checkout', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ licenseId }),
})
const res = await r.json()
if (!r.ok) throw new Error(res.error || 'checkout failed')
toast.success('Weiterleitung zu Stripe…', { id: t })
window.location.href = res.url
} catch (err) {
toast.error(err instanceof Error ? err.message : 'Checkout fehlgeschlagen', { id: t })
} finally {
setPaying(null)
}
}
// Find licenses with a price > 0 that could be paid
const payableLicenses = data.licenses.filter((l) => l.netPriceCents > 0 && l.status === 'active' && !l.parentId)
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -512,6 +550,46 @@ function PortalInvoices({ data }: { data: PortalData }) {
<p className="text-xs text-muted-foreground">Deine Rechnungen — Ansicht nur für dein Unternehmen.</p> <p className="text-xs text-muted-foreground">Deine Rechnungen — Ansicht nur für dein Unternehmen.</p>
</div> </div>
</div> </div>
{/* Pay subscription */}
{payableLicenses.length > 0 && (
<Card className="border-foreground/30 bg-foreground/5">
<CardContent className="p-4">
<div className="flex items-start justify-between gap-3">
<div className="flex items-start gap-2">
<CreditCard className="mt-0.5 size-4 text-foreground" />
<div>
<p className="text-sm font-medium">Abonnement bezahlen</p>
<p className="text-xs text-muted-foreground">
{payableLicenses.length} Lizenz(en) mit offener Zahlung. Klicke auf „Jetzt zahlen", um zur Stripe-Checkout-Seite zu gelangen.
</p>
</div>
</div>
</div>
<div className="mt-3 space-y-2">
{payableLicenses.map((l) => (
<div key={l.id} className="flex items-center justify-between rounded-md border border-border p-2">
<div>
<p className="text-xs font-medium">{l.product} — {l.plan}</p>
<p className="text-[10px] text-muted-foreground">{formatEuro(l.netPriceCents)} / {l.billingCycle === 'yearly' ? 'Jahr' : 'Monat'}</p>
</div>
<Button
size="sm"
className="gap-1.5"
disabled={paying === l.id}
onClick={() => pay(l.id)}
>
{paying === l.id && <Loader2 className="size-3.5 animate-spin" />}
<CreditCard className="size-3.5" />
Jetzt zahlen
</Button>
</div>
))}
</div>
</CardContent>
</Card>
)}
<Card> <Card>
<CardContent className="p-0"> <CardContent className="p-0">
<div className="overflow-x-auto"> <div className="overflow-x-auto">
@@ -557,6 +635,47 @@ function PortalInvoices({ data }: { data: PortalData }) {
} }
function PortalTickets({ data }: { data: PortalData }) { function PortalTickets({ data }: { data: PortalData }) {
const companyId = data.company.id
const [showCreate, setShowCreate] = useState(false)
const [subject, setSubject] = useState('')
const [category, setCategory] = useState('anfrage')
const [priority, setPriority] = useState<'low' | 'normal' | 'high' | 'urgent'>('normal')
const [message, setMessage] = useState('')
const [creating, setCreating] = useState(false)
const createTicket = async () => {
if (!subject.trim() || !message.trim()) return
setCreating(true)
const t = toast.loading('Ticket wird erstellt…')
try {
const r = await fetch('/api/aos/tickets', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
companyId,
subject: subject.trim(),
categoryId: category,
priority,
message: message.trim(),
fromName: data.company.name,
}),
})
const res = await r.json()
if (!r.ok) throw new Error(res.error || 'create failed')
toast.success(`Ticket ${res.ticket?.number ?? ''} erstellt`, { id: t })
setShowCreate(false)
setSubject('')
setCategory('anfrage')
setPriority('normal')
setMessage('')
window.location.reload()
} catch (err) {
toast.error(err instanceof Error ? err.message : 'Erstellung fehlgeschlagen', { id: t })
} finally {
setCreating(false)
}
}
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@@ -567,7 +686,9 @@ function PortalTickets({ data }: { data: PortalData }) {
<p className="text-xs text-muted-foreground">Support-Anfragen und Konversationen.</p> <p className="text-xs text-muted-foreground">Support-Anfragen und Konversationen.</p>
</div> </div>
</div> </div>
<Button size="sm"><LifeBuoy className="size-4" />Neues Ticket</Button> <Button size="sm" onClick={() => setShowCreate(true)}>
<Plus className="size-4" />Neues Ticket
</Button>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
{data.tickets.map((t) => ( {data.tickets.map((t) => (
@@ -587,11 +708,94 @@ function PortalTickets({ data }: { data: PortalData }) {
))} ))}
{data.tickets.length === 0 && <p className="py-8 text-center text-xs text-muted-foreground">Keine Tickets.</p>} {data.tickets.length === 0 && <p className="py-8 text-center text-xs text-muted-foreground">Keine Tickets.</p>}
</div> </div>
{/* Create Ticket Dialog */}
<Dialog open={showCreate} onOpenChange={setShowCreate}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle>Neues Ticket</DialogTitle>
<DialogDescription>
Support-Anfrage erstellen. Dein Ticket wird an den zuständigen Reseller oder DFM Solutions weitergeleitet.
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div className="space-y-1.5">
<Label className="text-xs">Betreff</Label>
<Input value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="Kurze Beschreibung des Problems" />
</div>
<div className="grid grid-cols-2 gap-3">
<div className="space-y-1.5">
<Label className="text-xs">Kategorie</Label>
<Select value={category} onValueChange={setCategory}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="anfrage">Anfrage</SelectItem>
<SelectItem value="bug">Fehler</SelectItem>
<SelectItem value="aenderung">Änderung</SelectItem>
<SelectItem value="rechnung">Rechnung</SelectItem>
<SelectItem value="konto">Konto</SelectItem>
<SelectItem value="hosting">Hosting</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1.5">
<Label className="text-xs">Priorität</Label>
<Select value={priority} onValueChange={(v) => setPriority(v as 'low' | 'normal' | 'high' | 'urgent')}>
<SelectTrigger className="w-full"><SelectValue /></SelectTrigger>
<SelectContent>
<SelectItem value="low">Niedrig</SelectItem>
<SelectItem value="normal">Normal</SelectItem>
<SelectItem value="high">Hoch</SelectItem>
<SelectItem value="urgent">Dringend</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-1.5">
<Label className="text-xs">Nachricht</Label>
<Textarea value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Beschreibe dein Anliegen…" rows={4} />
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setShowCreate(false)}>Abbrechen</Button>
<Button onClick={createTicket} disabled={creating || !subject.trim() || !message.trim()} className="gap-1.5">
{creating && <Loader2 className="size-3.5 animate-spin" />}
Erstellen
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div> </div>
) )
} }
function PortalLicenses({ data }: { data: PortalData }) { function PortalLicenses({ data }: { data: PortalData }) {
const [cancelling, setCancelling] = useState<string | null>(null)
const [showCancel, setShowCancel] = useState<string | null>(null)
const [cancelReason, setCancelReason] = useState('')
const cancelLicense = async (licenseId: string) => {
setCancelling(licenseId)
const t = toast.loading('Kündigung wird verarbeitet…')
try {
const r = await fetch(`/api/aos/licenses/${licenseId}/cancel`, {
method: 'PATCH',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ reason: cancelReason || undefined }),
})
const res = await r.json()
if (!r.ok) throw new Error(res.error || 'cancel failed')
toast.success(res.message || 'Lizenz gekündigt', { id: t, duration: 6000 })
setShowCancel(null)
setCancelReason('')
window.location.reload()
} catch (err) {
toast.error(err instanceof Error ? err.message : 'Kündigung fehlgeschlagen', { id: t })
} finally {
setCancelling(null)
}
}
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -616,8 +820,52 @@ function PortalLicenses({ data }: { data: PortalData }) {
{l.validUntil && <p>Gültig bis: {formatDate(l.validUntil)}</p>} {l.validUntil && <p>Gültig bis: {formatDate(l.validUntil)}</p>}
</div> </div>
</div> </div>
<div className="flex flex-col items-end gap-2">
<Badge variant="outline" className="text-[10px] capitalize">{l.status}</Badge> <Badge variant="outline" className="text-[10px] capitalize">{l.status}</Badge>
{l.status === 'active' && !l.parentId && !l.cancelledAt && (
<Button
size="sm"
variant="ghost"
className="h-7 gap-1 text-[10px] text-muted-foreground hover:text-foreground"
onClick={() => setShowCancel(l.id)}
>
<Ban className="size-3" />
Kündigen
</Button>
)}
</div> </div>
</div>
{/* Cancel dialog */}
{showCancel === l.id && (
<div className="mt-3 rounded-md border border-foreground/30 bg-foreground/5 p-3">
<p className="text-xs font-medium">Lizenz kündigen</p>
<p className="mt-1 text-[11px] text-muted-foreground">
{l.trialEndsAt && new Date(l.trialEndsAt) > new Date()
? 'Du befindest dich in der 14-Tage-Testphase — Kündigung wird sofort wirksam, keine Abbuchung.'
: `Kündigungsfrist: ${l.noticePeriodDays ?? 90} Tage. Wirksam zum ${new Date(Date.now() + (l.noticePeriodDays ?? 90) * 86400000).toLocaleDateString('de-DE')}.`}
</p>
<Input
className="mt-2"
value={cancelReason}
onChange={(e) => setCancelReason(e.target.value)}
placeholder="Grund (optional)"
/>
<div className="mt-2 flex gap-2">
<Button size="sm" variant="ghost" onClick={() => { setShowCancel(null); setCancelReason('') }}>Abbrechen</Button>
<Button
size="sm"
variant="destructive"
disabled={cancelling === l.id}
onClick={() => cancelLicense(l.id)}
className="gap-1.5"
>
{cancelling === l.id && <Loader2 className="size-3.5 animate-spin" />}
Kündigung bestätigen
</Button>
</div>
</div>
)}
</Card> </Card>
))} ))}
</div> </div>
+2
View File
@@ -29,6 +29,7 @@ import {
RefreshCw, RefreshCw,
Landmark, Landmark,
Server, Server,
Store,
} from 'lucide-react' } from 'lucide-react'
import { useAos, type ViewId } from '@/store/aos' import { useAos, type ViewId } from '@/store/aos'
import { translate } from '@/lib/i18n' import { translate } from '@/lib/i18n'
@@ -69,6 +70,7 @@ const NAV: {
items: [ items: [
{ id: 'licenses', label: 'Lizenzen', icon: KeyRound, permission: 'licenses:read' }, { id: 'licenses', label: 'Lizenzen', icon: KeyRound, permission: 'licenses:read' },
{ id: 'agency', label: 'Reseller', icon: Users, permission: 'admin' }, { id: 'agency', label: 'Reseller', icon: Users, permission: 'admin' },
{ id: 'reseller_portal', label: 'Reseller-Portal', icon: Store, permission: 'admin' },
{ id: 'instances', label: 'Instanzen', icon: Server, permission: 'admin' }, { id: 'instances', label: 'Instanzen', icon: Server, permission: 'admin' },
{ id: 'contracts', label: 'Verträge', icon: FileSignature, permission: 'contracts:read' }, { id: 'contracts', label: 'Verträge', icon: FileSignature, permission: 'contracts:read' },
{ id: 'expenses', label: 'Ausgaben', icon: Wallet, permission: 'expenses:read' }, { id: 'expenses', label: 'Ausgaben', icon: Wallet, permission: 'expenses:read' },
+11 -1
View File
@@ -29,6 +29,7 @@ const TITLES: Record<ViewId, { title: string; crumb: string }> = {
support: { title: 'Support', crumb: 'Lieferung / Tickets' }, support: { title: 'Support', crumb: 'Lieferung / Tickets' },
licenses: { title: 'Lizenzen', crumb: 'Betrieb / Lizenzen' }, licenses: { title: 'Lizenzen', crumb: 'Betrieb / Lizenzen' },
agency: { title: 'Reseller', crumb: 'Betrieb / Reseller' }, agency: { title: 'Reseller', crumb: 'Betrieb / Reseller' },
reseller_portal: { title: 'Reseller-Portal', crumb: 'Betrieb / Reseller-Portal' },
instances: { title: 'Instanzen', crumb: 'Betrieb / Instanzen' }, instances: { title: 'Instanzen', crumb: 'Betrieb / Instanzen' },
contracts: { title: 'Verträge', crumb: 'Betrieb / Verträge' }, contracts: { title: 'Verträge', crumb: 'Betrieb / Verträge' },
expenses: { title: 'Ausgaben', crumb: 'Betrieb / Ausgaben' }, expenses: { title: 'Ausgaben', crumb: 'Betrieb / Ausgaben' },
@@ -110,7 +111,16 @@ export function TopBar() {
<DropdownMenuItem>Profil</DropdownMenuItem> <DropdownMenuItem>Profil</DropdownMenuItem>
<DropdownMenuItem>Sitzungen</DropdownMenuItem> <DropdownMenuItem>Sitzungen</DropdownMenuItem>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuItem className="text-muted-foreground">Abmelden</DropdownMenuItem> <DropdownMenuItem
className="text-muted-foreground"
onSelect={async (e) => {
e.preventDefault()
await fetch('/api/auth/logout', { method: 'POST' })
window.location.href = '/login'
}}
>
Abmelden
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</div> </div>
File diff suppressed because it is too large. Load diff
+201 -180
View File
@@ -1,102 +1,90 @@
/** /**
* Dokploy API Client * Dokploy API Client (v2 — correct tRPC-based API)
* ------------------- * -----------------------------------------------
* Manages tenant instances on the Dokploy server: create applications from * Manages tenant instances on the Dokploy server.
* a Git repo, deploy, attach domains, create databases, suspend/delete. *
* API format (verified from @dokploy/mcp source):
* - Base URL: {DOKPLOY_URL}/api
* - Auth: x-api-key header (NOT Authorization: Bearer)
* - Endpoints: /application.create, /application.deploy, /application.delete, etc.
* - Application creation is multi-step:
* 1. POST /application.create { name, environmentId, sourceType: 'gitea' }
* 2. POST /application.saveGiteaProvider { applicationId, giteaOwner, giteaRepository, giteaBranch, giteaBuildPath }
* (or saveGitProvider for generic git, saveGithubProvider for github)
* 3. POST /application.saveEnvironment { applicationId, env: [...] }
* 4. POST /application.deploy { applicationId }
* *
* Config (env): * Config (env):
* DOKPLOY_URL - e.g. https://cp.project-url.eu * DOKPLOY_URL - e.g. https://cp.project-url.eu
* DOKPLOY_API_KEY - bearer token * DOKPLOY_API_KEY - x-api-key value
* DOKPLOY_SERVER_ID - the Dokploy server ID to deploy to (default "default") * DOKPLOY_ENVIRONMENT_ID - the Dokploy environment ID to create apps under
* DOKPLOY_PROJECT_ID - the Dokploy project to put tenant apps under * DOKPLOY_SERVER_ID - (optional) specific server, null = default
*
* NOTE: Dokploy API endpoints should be verified against the current API docs
* at implementation time. The endpoints below are based on the Dokploy REST API.
* See: https://docs.dokploy.com/docs/api
*/ */
export interface DokployConfig { export interface DokployConfig {
url: string url: string
apiKey: string apiKey: string
serverId?: string environmentId?: string
projectId?: string serverId?: string | null
} }
export interface DokployApp { export interface DokployApp {
applicationId: string applicationId: string
name: string name: string
appName?: string
status?: string status?: string
url?: string previewDomain?: string
createdAt?: string createdAt?: string
} }
export interface DokployDatabase {
databaseId: string
name: string
type: string // postgres|mysql|redis|...
host: string
port: number
database: string
username: string
password: string
externalUrl?: string
}
export interface DokployDomain { export interface DokployDomain {
domainId: string domainId: string
hostName: string hostName: string
applicationId: string applicationId: string
https: boolean https: boolean
certificateStatus?: string
} }
export interface ProvisionInstanceInput { export interface ProvisionInstanceInput {
name: string name: string
subdomain: string subdomain: string
gitRepo: string // e.g. https://github.com/cetinmustafa83/restov1 gitRepo: string
gitBranch: string // e.g. main gitBranch: string
buildPath?: string // e.g. / (repo root, default) buildPath?: string
envVars: Record<string, string> envVars: Record<string, string>
// Resource limits (Dokploy applies these as container constraints) gitProvider?: 'gitea' | 'github' | 'git' // default: gitea
cpuLimit?: string // e.g. "0.5" = 50% of one core // Resource limits (applied via application.update after creation)
memoryLimit?: string // e.g. "512m" cpuLimit?: string
// Database memoryLimit?: string
databaseName?: string // if set, a Postgres DB is created for this instance
} }
export interface ProvisionInstanceResult { export interface ProvisionInstanceResult {
app: DokployApp app: DokployApp
database?: DokployDatabase domain?: DokployDomain
domain: DokployDomain
url: string url: string
} }
class DokployError extends Error { class DokployError extends Error {
constructor( constructor(message: string, public status: number, public endpoint: string, public body?: unknown) {
message: string,
public status: number,
public endpoint: string,
public body?: unknown
) {
super(message) super(message)
this.name = 'DokployError' this.name = 'DokployError'
} }
} }
export function createDokployClient(config: DokployConfig) { export function createDokployClient(config: DokployConfig) {
const baseUrl = config.url.replace(/\/$/, '') const baseUrl = config.url.replace(/\/+$/, '') + '/api'
const serverId = config.serverId ?? 'default'
const headers: Record<string, string> = { const headers: Record<string, string> = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer ${config.apiKey}`, Accept: 'application/json',
'x-api-key': config.apiKey,
} }
async function call<T = unknown>(endpoint: string, body?: Record<string, unknown>, method = 'POST'): Promise<T> { async function call<T = unknown>(path: string, body?: Record<string, unknown>, method = 'POST'): Promise<T> {
const url = `${baseUrl}${endpoint}` const url = `${baseUrl}${path}`
const isGet = method === 'GET'
const res = await fetch(url, { const res = await fetch(url, {
method, method,
headers, headers,
body: body ? JSON.stringify(body) : undefined, body: !isGet && body ? JSON.stringify(body) : undefined,
}) })
const text = await res.text() const text = await res.text()
let json: unknown let json: unknown
@@ -107,9 +95,9 @@ export function createDokployClient(config: DokployConfig) {
} }
if (!res.ok) { if (!res.ok) {
throw new DokployError( throw new DokployError(
`Dokploy API ${endpoint} failed: HTTP ${res.status}`, `Dokploy API ${path} failed: HTTP ${res.status}`,
res.status, res.status,
endpoint, path,
json json
) )
} }
@@ -120,111 +108,130 @@ export function createDokployClient(config: DokployConfig) {
async function createApplication(input: { async function createApplication(input: {
name: string name: string
environmentId: string
sourceType?: string
serverId?: string | null
description?: string description?: string
gitRepo: string
gitBranch: string
buildPath?: string
envVars?: Record<string, string>
cpuLimit?: string
memoryLimit?: string
}): Promise<DokployApp> { }): Promise<DokployApp> {
const body: Record<string, unknown> = { const body: Record<string, unknown> = {
name: input.name, name: input.name,
description: input.description ?? `Tenant instance: ${input.name}`, environmentId: input.environmentId,
serverId, sourceType: input.sourceType ?? 'gitea',
projectName: config.projectId ?? 'default',
sourceType: 'git',
gitRepository: input.gitRepo,
gitBranch: input.gitBranch,
buildPath: input.buildPath ?? '/',
// Dokploy expects env vars as a JSON string
env: JSON.stringify(input.envVars ?? {}),
cpuLimit: input.cpuLimit ?? '0.5',
memoryLimit: input.memoryLimit ?? '512m',
} }
const res = await call<{ applicationId?: string; app?: { applicationId: string }; [k: string]: unknown }>('/api/application.create', body) if (input.serverId) body.serverId = input.serverId
const applicationId = res.applicationId ?? (res.app as { applicationId: string } | undefined)?.applicationId if (input.description) body.description = input.description
const res = await call<{ applicationId?: string; app?: DokployApp; [k: string]: unknown }>(
'/application.create',
body
)
const applicationId = res.applicationId ?? (res.app as DokployApp | undefined)?.applicationId
if (!applicationId) { if (!applicationId) {
throw new DokployError('Dokploy createApplication returned no applicationId', 200, '/api/application.create', res) throw new DokployError('createApplication returned no applicationId', 200, '/application.create', res)
} }
return { applicationId, name: input.name, status: 'created' } return { applicationId, name: input.name, status: 'created' }
} }
async function deployApplication(applicationId: string): Promise<{ deployId: string; status: string }> { async function saveGiteaProvider(input: {
const res = await call<{ deployId?: string; jobId?: string; status?: string }>('/api/application.deploy', { applicationId }) applicationId: string
return { deployId: res.deployId ?? res.jobId ?? '', status: res.status ?? 'deploying' } giteaOwner: string
giteaRepository: string
giteaBranch: string
giteaBuildPath?: string | null
giteaId?: string | null
}): Promise<void> {
await call('/application.saveGiteaProvider', {
applicationId: input.applicationId,
giteaOwner: input.giteaOwner,
giteaRepository: input.giteaRepository,
giteaBranch: input.giteaBranch,
giteaBuildPath: input.giteaBuildPath ?? '/',
giteaId: input.giteaId ?? null,
})
} }
async function getApplication(applicationId: string): Promise<DokployApp & { status?: string; url?: string }> { async function saveGitProvider(input: {
applicationId: string
gitProviderOwner?: string | null
gitProviderRepository?: string | null
gitProviderBranch?: string
gitProviderBuildPath?: string | null
gitProviderId?: string | null
}): Promise<void> {
await call('/application.saveGitProvider', {
applicationId: input.applicationId,
gitProviderOwner: input.gitProviderOwner ?? null,
gitProviderRepository: input.gitProviderRepository ?? null,
gitProviderBranch: input.gitProviderBranch ?? 'main',
gitProviderBuildPath: input.gitProviderBuildPath ?? '/',
gitProviderId: input.gitProviderId ?? null,
})
}
async function saveGithubProvider(input: {
applicationId: string
githubOwner: string
githubRepository: string
githubBranch: string
githubBuildPath?: string | null
githubId?: string | null
}): Promise<void> {
await call('/application.saveGithubProvider', {
applicationId: input.applicationId,
githubOwner: input.githubOwner,
githubRepository: input.githubRepository,
githubBranch: input.githubBranch,
githubBuildPath: input.githubBuildPath ?? '/',
githubId: input.githubId ?? null,
})
}
async function saveEnvironment(applicationId: string, envVars: Record<string, string>): Promise<void> {
// Dokploy expects env as array of { key, value } objects OR a JSON string
const envArray = Object.entries(envVars).map(([key, value]) => ({ key, value }))
await call('/application.saveEnvironment', {
applicationId,
env: JSON.stringify(envArray),
})
}
async function deployApplication(applicationId: string): Promise<{ jobId?: string; status: string }> {
const res = await call<{ jobId?: string; deployId?: string; status?: string }>('/application.deploy', {
applicationId,
})
return { jobId: res.jobId ?? res.deployId, status: res.status ?? 'deploying' }
}
async function getApplication(applicationId: string): Promise<DokployApp> {
const res = await call<DokployApp & { applicationStatus?: string; previewDomain?: string }>( const res = await call<DokployApp & { applicationStatus?: string; previewDomain?: string }>(
`/api/application.one`, '/application.one',
{ applicationId }, { applicationId },
'GET'
) )
return { return {
applicationId: res.applicationId, applicationId: res.applicationId,
name: res.name, name: res.name,
appName: res.appName,
status: res.applicationStatus ?? res.status, status: res.applicationStatus ?? res.status,
url: res.previewDomain ?? res.url, previewDomain: res.previewDomain,
createdAt: res.createdAt, createdAt: res.createdAt,
} }
} }
async function deleteApplication(applicationId: string): Promise<void> { async function deleteApplication(applicationId: string): Promise<void> {
await call('/api/application.delete', { applicationId, deleteVolumes: true }) await call('/application.delete', { applicationId })
} }
async function stopApplication(applicationId: string): Promise<void> { async function stopApplication(applicationId: string): Promise<void> {
await call('/api/application.stop', { applicationId }) await call('/application.stop', { applicationId })
} }
async function startApplication(applicationId: string): Promise<void> { async function startApplication(applicationId: string): Promise<void> {
await call('/api/application.start', { applicationId }) await call('/application.start', { applicationId })
} }
async function updateEnv(applicationId: string, envVars: Record<string, string>): Promise<void> { async function redeployApplication(applicationId: string): Promise<void> {
await call('/api/application.update', { await call('/application.redeploy', { applicationId })
applicationId,
env: JSON.stringify(envVars),
})
}
// --- Databases (Postgres) ---
async function createPostgresDatabase(input: {
name: string
appName: string // the application this DB belongs to
description?: string
externalUrl?: boolean
}): Promise<DokployDatabase> {
const body: Record<string, unknown> = {
name: input.name,
appName: input.appName,
description: input.description ?? `DB for ${input.appName}`,
serverId,
projectName: config.projectId ?? 'default',
externalUrl: input.externalUrl ?? false,
}
const res = await call<Record<string, unknown>>('/api/database.postgres.create', body)
// The response shape varies between Dokploy versions; handle both.
const db = (res.database as Record<string, unknown> | undefined) ?? res
const databaseId = (db.databaseId as string | undefined) ?? (res.databaseId as string | undefined)
if (!databaseId) {
throw new DokployError('Dokploy createDatabase returned no databaseId', 200, '/api/database.postgres.create', res)
}
return {
databaseId,
name: (db.name as string | undefined) ?? input.name,
type: 'postgres',
host: (db.host as string | undefined) ?? 'postgres',
port: (db.port as number | undefined) ?? 5432,
database: (db.database as string | undefined) ?? input.name,
username: (db.username as string | undefined) ?? 'postgres',
password: (db.password as string | undefined) ?? '',
}
}
async function deleteDatabase(databaseId: string): Promise<void> {
await call('/api/database.postgres.delete', { databaseId })
} }
// --- Domains --- // --- Domains ---
@@ -235,20 +242,17 @@ export function createDokployClient(config: DokployConfig) {
path?: string path?: string
port?: number port?: number
https?: boolean https?: boolean
certificateType?: 'letsencrypt' | 'none'
}): Promise<DokployDomain> { }): Promise<DokployDomain> {
const body: Record<string, unknown> = { const res = await call<{ domainId?: string; id?: string }>('/domain.create', {
applicationId: input.applicationId, applicationId: input.applicationId,
hostName: input.hostName, hostName: input.hostName,
path: input.path ?? '/', path: input.path ?? '/',
port: input.port ?? 3000, port: input.port ?? 3000,
https: input.https ?? true, https: input.https ?? true,
certificateType: input.certificateType ?? 'letsencrypt', })
}
const res = await call<{ domainId?: string; id?: string; hostName?: string; https?: boolean }>('/api/domain.create', body)
const domainId = res.domainId ?? res.id const domainId = res.domainId ?? res.id
if (!domainId) { if (!domainId) {
throw new DokployError('Dokploy createDomain returned no domainId', 200, '/api/domain.create', res) throw new DokployError('createDomain returned no domainId', 200, '/domain.create', res)
} }
return { return {
domainId, domainId,
@@ -259,55 +263,84 @@ export function createDokployClient(config: DokployConfig) {
} }
async function deleteDomain(domainId: string): Promise<void> { async function deleteDomain(domainId: string): Promise<void> {
await call('/api/domain.delete', { domainId }) await call('/domain.delete', { domainId })
} }
// --- High-level: provision a full instance --- // --- High-level: provision a full instance ---
async function provisionInstance(input: ProvisionInstanceInput): Promise<ProvisionInstanceResult> { async function provisionInstance(input: ProvisionInstanceInput): Promise<ProvisionInstanceResult> {
// 1. Create application from Git repo const environmentId = config.environmentId ?? ''
if (!environmentId) {
throw new DokployError('DOKPLOY_ENVIRONMENT_ID not configured', 500, 'config')
}
// 1. Create application
const app = await createApplication({ const app = await createApplication({
name: input.name, name: input.name,
gitRepo: input.gitRepo, environmentId,
gitBranch: input.gitBranch, sourceType: input.gitProvider ?? 'gitea',
buildPath: '/', serverId: config.serverId,
envVars: input.envVars, description: `Tenant instance: ${input.subdomain}`,
cpuLimit: input.cpuLimit,
memoryLimit: input.memoryLimit,
}) })
// 2. (Optional) Create Postgres database // 2. Save Git provider (repo connection)
let database: DokployDatabase | undefined // Parse git repo URL: https://git.dfmpanel.eu/dfmsolutions/AOS.git
if (input.databaseName) { // → owner: dfmsolutions, repo: AOS
database = await createPostgresDatabase({ const gitMatch = input.gitRepo.match(/\/([^/]+)\/([^/]+?)(?:\.git)?$/)
name: input.databaseName, const owner = gitMatch?.[1] ?? ''
appName: input.name, const repo = gitMatch?.[2] ?? ''
if (input.gitProvider === 'github' || input.gitRepo.includes('github.com')) {
await saveGithubProvider({
applicationId: app.applicationId,
githubOwner: owner,
githubRepository: repo,
githubBranch: input.gitBranch,
githubBuildPath: input.buildPath ?? '/',
}) })
// Inject DATABASE_URL into the app's env } else if (input.gitProvider === 'gitea' || input.gitRepo.includes('git.dfmpanel.eu')) {
const dbUrl = `postgresql://${database.username}:${database.password}@${database.host}:${database.port}/${database.database}` await saveGiteaProvider({
await updateEnv(app.applicationId, { applicationId: app.applicationId,
...input.envVars, giteaOwner: owner,
DATABASE_URL: dbUrl, giteaRepository: repo,
giteaBranch: input.gitBranch,
giteaBuildPath: input.buildPath ?? '/',
})
} else {
// Generic git
await saveGitProvider({
applicationId: app.applicationId,
gitProviderOwner: owner,
gitProviderRepository: repo,
gitProviderBranch: input.gitBranch,
gitProviderBuildPath: input.buildPath ?? '/',
}) })
} }
// 3. Attach domain (subdomain.platform-domain) // 3. Save environment variables
const hostName = input.subdomain await saveEnvironment(app.applicationId, input.envVars)
const domain = await createDomain({
// 4. Deploy
await deployApplication(app.applicationId)
// 5. Attach domain (optional — can be done later)
let domain: DokployDomain | undefined
try {
domain = await createDomain({
applicationId: app.applicationId, applicationId: app.applicationId,
hostName, hostName: input.subdomain,
port: 3000, port: 3000,
https: true, https: true,
}) })
} catch (e) {
// 4. Trigger deploy // Domain creation is non-fatal — app is already deployed
await deployApplication(app.applicationId) console.warn('[dokploy] Domain creation failed (non-fatal):', e instanceof Error ? e.message : e)
}
return { return {
app, app,
database,
domain, domain,
url: `https://${hostName}`, url: `https://${input.subdomain}`,
} }
} }
@@ -315,14 +348,13 @@ export function createDokployClient(config: DokployConfig) {
async function teardownInstance(input: { async function teardownInstance(input: {
dokployAppId?: string dokployAppId?: string
dokployDbId?: string dokployDomainId?: string
dnsDomainId?: string // Dokploy domain ID
}): Promise<{ steps: string[] }> { }): Promise<{ steps: string[] }> {
const steps: string[] = [] const steps: string[] = []
// Remove domain first (stop traffic) // Remove domain first (stop traffic)
if (input.dnsDomainId) { if (input.dokployDomainId) {
try { try {
await deleteDomain(input.dnsDomainId) await deleteDomain(input.dokployDomainId)
steps.push('domain.removed') steps.push('domain.removed')
} catch (e) { } catch (e) {
if (e instanceof DokployError && e.status !== 404) { if (e instanceof DokployError && e.status !== 404) {
@@ -330,17 +362,6 @@ export function createDokployClient(config: DokployConfig) {
} }
} }
} }
// Delete database
if (input.dokployDbId) {
try {
await deleteDatabase(input.dokployDbId)
steps.push('database.removed')
} catch (e) {
if (e instanceof DokployError && e.status !== 404) {
steps.push(`database.error: ${e.message}`)
}
}
}
// Delete application (+ volumes) // Delete application (+ volumes)
if (input.dokployAppId) { if (input.dokployAppId) {
try { try {
@@ -358,14 +379,16 @@ export function createDokployClient(config: DokployConfig) {
return { return {
// Low-level // Low-level
createApplication, createApplication,
saveGiteaProvider,
saveGitProvider,
saveGithubProvider,
saveEnvironment,
deployApplication, deployApplication,
getApplication, getApplication,
deleteApplication, deleteApplication,
stopApplication, stopApplication,
startApplication, startApplication,
updateEnv, redeployApplication,
createPostgresDatabase,
deleteDatabase,
createDomain, createDomain,
deleteDomain, deleteDomain,
call, call,
@@ -377,8 +400,6 @@ export function createDokployClient(config: DokployConfig) {
export type DokployClient = ReturnType<typeof createDokployClient> export type DokployClient = ReturnType<typeof createDokployClient>
// --- Factory: create from env ---
export function createDokployClientFromEnv(): DokployClient | null { export function createDokployClientFromEnv(): DokployClient | null {
const url = process.env.DOKPLOY_URL const url = process.env.DOKPLOY_URL
const apiKey = process.env.DOKPLOY_API_KEY const apiKey = process.env.DOKPLOY_API_KEY
@@ -386,7 +407,7 @@ export function createDokployClientFromEnv(): DokployClient | null {
return createDokployClient({ return createDokployClient({
url, url,
apiKey, apiKey,
serverId: process.env.DOKPLOY_SERVER_ID, environmentId: process.env.DOKPLOY_ENVIRONMENT_ID,
projectId: process.env.DOKPLOY_PROJECT_ID, serverId: process.env.DOKPLOY_SERVER_ID ?? null,
}) })
} }
+118
View File
@@ -0,0 +1,118 @@
import type { Transporter } from 'nodemailer'
import nodemailer from 'nodemailer'
/**
* Email Client
* ------------
* Sends transactional emails (agency approval, license key delivery, ticket
* notifications, invoice sent).
*
* Config (env):
* MAIL_SMTP_HOST - e.g. smtp.your-server.de
* MAIL_SMTP_PORT - 587 (STARTTLS) or 465 (SSL)
* MAIL_USER - SMTP username
* MAIL_PASSWORD - SMTP password
* MAIL_FROM - sender email (e.g. "AOS <noreply@dfmpanel.eu>")
*/
let transporter: Transporter | null = null
function getTransporter(): Transporter | null {
const host = process.env.MAIL_SMTP_HOST
const port = process.env.MAIL_SMTP_PORT
const user = process.env.MAIL_USER
const pass = process.env.MAIL_PASSWORD
if (!host || !user || !pass) return null
if (!transporter) {
transporter = nodemailer.createTransport({
host,
port: port ? parseInt(port, 10) : 587,
secure: parseInt(port ?? '587', 10) === 465,
auth: { user, pass },
})
}
return transporter
}
export interface EmailInput {
to: string
subject: string
text?: string
html?: string
}
export async function sendEmail(input: EmailInput): Promise<{ ok: boolean; error?: string }> {
const t = getTransporter()
if (!t) {
console.warn('[mail] SMTP not configured — email would have been sent to:', input.to, '| subject:', input.subject)
return { ok: false, error: 'SMTP not configured' }
}
const from = process.env.MAIL_FROM || 'AOS <noreply@dfmpanel.eu>'
try {
await t.sendMail({
from,
to: input.to,
subject: input.subject,
text: input.text || input.html?.replace(/<[^>]*>/g, ''),
html: input.html || input.text,
})
return { ok: true }
} catch (err) {
return { ok: false, error: err instanceof Error ? err.message : 'send failed' }
}
}
// --- Pre-built email templates ---
export async function sendAgencyApprovedEmail(input: {
to: string
companyName: string
discountPct: number
}): Promise<void> {
await sendEmail({
to: input.to,
subject: `Ihre Reseller-Bewerbung wurde genehmigt — ${input.discountPct}% Rabatt`,
text: `Guten Tag,\n\nIhre Bewerbung als Reseller wurde genehmigt.\n\nUnternehmen: ${input.companyName}\nIhr Rabatt: ${input.discountPct}% auf alle Lizenzen\n\nSie können jetzt eigene Kunden anlegen und lizenzieren.\n\nBesuchen Sie: https://dfmpanel.eu\n\nMit freundlichen Grüßen\nDFM Solutions`,
html: `<p>Guten Tag,</p><p>Ihre Bewerbung als Reseller wurde <strong>genehmigt</strong>.</p><p><strong>Unternehmen:</strong> ${input.companyName}<br><strong>Ihr Rabatt:</strong> ${input.discountPct}% auf alle Lizenzen</p><p>Sie können jetzt eigene Kunden anlegen und lizenzieren.</p><p><a href="https://dfmpanel.eu">Zum Portal →</a></p><p>Mit freundlichen Grüßen<br>DFM Solutions</p>`,
})
}
export async function sendAgencyRejectedEmail(input: {
to: string
companyName: string
reason: string
}): Promise<void> {
await sendEmail({
to: input.to,
subject: 'Ihre Reseller-Bewerbung',
text: `Guten Tag,\n\nIhre Bewerbung als Reseller wurde leider abgelehnt.\n\nUnternehmen: ${input.companyName}\nGrund: ${input.reason}\n\nBei Fragen kontaktieren Sie uns unter support@dfmpanel.eu\n\nMit freundlichen Grüßen\nDFM Solutions`,
html: `<p>Guten Tag,</p><p>Ihre Bewerbung als Reseller wurde leider <strong>abgelehnt</strong>.</p><p><strong>Unternehmen:</strong> ${input.companyName}<br><strong>Grund:</strong> ${input.reason}</p><p>Bei Fragen kontaktieren Sie uns unter support@dfmpanel.eu</p><p>Mit freundlichen Grüßen<br>DFM Solutions</p>`,
})
}
export async function sendLicenseKeyEmail(input: {
to: string
licenseKey: string
product: string
plan: string
}): Promise<void> {
await sendEmail({
to: input.to,
subject: `Ihre Lizenz für ${input.product} (${input.plan.toUpperCase()})`,
text: `Guten Tag,\n\nIhre Lizenz wurde erstellt.\n\nProdukt: ${input.product}\nPlan: ${input.plan}\nLizenzschlüssel: ${input.licenseKey}\n\nSpeichern Sie den Schlüssel sicher. Sie benötigen ihn zur Aktivierung Ihrer Software.\n\nMit freundlichen Grüßen\nDFM Solutions`,
html: `<p>Guten Tag,</p><p>Ihre Lizenz wurde erstellt.</p><p><strong>Produkt:</strong> ${input.product}<br><strong>Plan:</strong> ${input.plan}<br><strong>Lizenzschlüssel:</strong> <code style="font-size: 16px; background: #f0f0f0; padding: 8px; border-radius: 4px;">${input.licenseKey}</code></p><p>Speichern Sie den Schlüssel sicher. Sie benötigen ihn zur Aktivierung Ihrer Software.</p><p>Mit freundlichen Grüßen<br>DFM Solutions</p>`,
})
}
export async function sendTicketCreatedEmail(input: {
to: string
ticketNumber: string
subject: string
}): Promise<void> {
await sendEmail({
to: input.to,
subject: `Ticket ${input.ticketNumber} wurde erstellt`,
text: `Ihr Support-Ticket wurde erstellt.\n\nTicket: ${input.ticketNumber}\nBetreff: ${input.subject}\n\nWir werden uns so schnell wie möglich um Ihr Anliegen kümmern.\n\nMit freundlichen Grüßen\nDFM Solutions`,
html: `<p>Ihr Support-Ticket wurde erstellt.</p><p><strong>Ticket:</strong> ${input.ticketNumber}<br><strong>Betreff:</strong> ${input.subject}</p><p>Wir werden uns so schnell wie möglich um Ihr Anliegen kümmern.</p>`,
})
}
+3
View File
@@ -29,6 +29,7 @@ const de: Dict = {
'nav.support': 'Support', 'nav.support': 'Support',
'nav.licenses': 'Lizenzen', 'nav.licenses': 'Lizenzen',
'nav.agency': 'Reseller', 'nav.agency': 'Reseller',
'nav.reseller_portal': 'Reseller-Portal',
'nav.instances': 'Instanzen', 'nav.instances': 'Instanzen',
'nav.contracts': 'Verträge', 'nav.contracts': 'Verträge',
'nav.expenses': 'Ausgaben', 'nav.expenses': 'Ausgaben',
@@ -87,6 +88,7 @@ const en: Dict = {
'nav.support': 'Support', 'nav.support': 'Support',
'nav.licenses': 'Licenses', 'nav.licenses': 'Licenses',
'nav.agency': 'Reseller', 'nav.agency': 'Reseller',
'nav.reseller_portal': 'Reseller Portal',
'nav.instances': 'Instances', 'nav.instances': 'Instances',
'nav.contracts': 'Contracts', 'nav.contracts': 'Contracts',
'nav.expenses': 'Expenses', 'nav.expenses': 'Expenses',
@@ -141,6 +143,7 @@ const tr: Dict = {
'nav.support': 'Destek', 'nav.support': 'Destek',
'nav.licenses': 'Lisanslar', 'nav.licenses': 'Lisanslar',
'nav.agency': 'Bayi', 'nav.agency': 'Bayi',
'nav.reseller_portal': 'Bayi Portal',
'nav.instances': 'Sunucular', 'nav.instances': 'Sunucular',
'nav.contracts': 'Sözleşmeler', 'nav.contracts': 'Sözleşmeler',
'nav.expenses': 'Giderler', 'nav.expenses': 'Giderler',
+119
View File
@@ -0,0 +1,119 @@
import Stripe from 'stripe'
/**
* Stripe Client
* --------------
* Creates Stripe checkout sessions for license subscriptions and handles
* webhook events (invoice.paid, subscription lifecycle).
*
* Config (env):
* STRIPE_SECRET_KEY - sk_test_... or sk_live_...
* STRIPE_WEBHOOK_SECRET - whsec_... (for webhook verification)
* STRIPE_PUBLISHABLE_KEY - pk_test_... or pk_live_... (client-side)
* AOS_PUBLIC_URL - base URL for success/cancel redirects
*/
let stripeInstance: Stripe | null = null
export function getStripe(): Stripe | null {
const key = process.env.STRIPE_SECRET_KEY
if (!key) return null
if (!stripeInstance) {
stripeInstance = new Stripe(key, {
apiVersion: '2025-10-28.acacia' as Stripe.LatestApiVersion,
typescript: true,
})
}
return stripeInstance
}
// Plan → Stripe Price mapping (create these prices in Stripe dashboard)
// If STRIPE_PRICE_STARTER, STRIPE_PRICE_PRO, STRIPE_PRICE_ENTERPRISE env
// vars are set, they override these defaults.
const PLAN_PRICES: Record<string, string> = {
starter: process.env.STRIPE_PRICE_STARTER ?? '',
pro: process.env.STRIPE_PRICE_PRO ?? '',
enterprise: process.env.STRIPE_PRICE_ENTERPRISE ?? '',
}
export function getStripePriceId(plan: string, cycle: 'monthly' | 'yearly'): string | null {
// If we have per-plan price IDs, use them.
// Otherwise return null (checkout session will use custom amount).
const base = PLAN_PRICES[plan]
if (!base) return null
// For yearly, append '_yearly' suffix (create separate price in Stripe)
return cycle === 'yearly' ? `${base}_yearly` : base
}
// Create a checkout session for a license subscription
export async function createCheckoutSession(input: {
licenseId: string
licenseKey: string
product: string
plan: string
billingCycle: 'monthly' | 'yearly'
netPriceCents: number
customerEmail?: string
successUrl?: string
cancelUrl?: string
}): Promise<{ url: string } | { error: string }> {
const stripe = getStripe()
if (!stripe) return { error: 'Stripe not configured (STRIPE_SECRET_KEY missing)' }
const baseUrl = process.env.AOS_PUBLIC_URL || 'https://dfmpanel.eu'
const successUrl = input.successUrl || `${baseUrl}/portal?tab=licenses&status=success&license=${input.licenseId}`
const cancelUrl = input.cancelUrl || `${baseUrl}/portal?tab=licenses&status=cancelled`
try {
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
customer_email: input.customerEmail,
line_items: [
{
price_data: {
currency: 'eur',
product_data: {
name: `${input.product} — ${input.plan.toUpperCase()}`,
description: `Lizenz ${input.licenseKey} (${input.billingCycle === 'yearly' ? 'jährlich' : 'monatlich'})`,
},
unit_amount: input.netPriceCents,
recurring: {
interval: input.billingCycle === 'yearly' ? 'year' : 'month',
},
},
quantity: 1,
},
],
metadata: {
licenseId: input.licenseId,
licenseKey: input.licenseKey,
product: input.product,
plan: input.plan,
},
success_url: successUrl,
cancel_url: cancelUrl,
locale: 'de',
allow_promotion_codes: true,
})
return { url: session.url ?? '' }
} catch (err) {
return { error: err instanceof Error ? err.message : 'Stripe checkout failed' }
}
}
// Construct webhook event from raw body + signature
export function constructWebhookEvent(
body: string | Buffer,
signature: string
): Stripe.Event | null {
const stripe = getStripe()
if (!stripe) return null
const secret = process.env.STRIPE_WEBHOOK_SECRET
if (!secret) return null
try {
return stripe.webhooks.constructEvent(body, signature, secret)
} catch {
return null
}
}
+157
View File
@@ -0,0 +1,157 @@
import { NextRequest, NextResponse } from 'next/server'
// Middleware: protects all routes except public ones.
// Uses a simple session cookie (HMAC-signed) for auth.
// Password is set via ADMIN_PASSWORD env var.
const PUBLIC_PATHS = [
'/api/health',
'/api/aos/seed-prod',
'/api/aos/licenses/check',
'/api/aos/licenses/validate',
'/api/aos/stripe/webhook',
'/api/auth/login',
'/login',
'/_next',
'/favicon.ico',
'/manifest.json',
'/icons/',
'/apple-touch-icon',
]
const PUBLIC_API_PREFIXES = [
'/api/health',
'/api/aos/seed-prod',
'/api/aos/licenses/check',
'/api/aos/licenses/validate',
'/api/aos/stripe/webhook',
'/api/auth/login',
'/api/v1/', // public REST API (token-auth'd separately)
'/api/mcp', // MCP (token-auth'd)
]
function isPublic(pathname: string): boolean {
// Exact matches
if (PUBLIC_PATHS.includes(pathname)) return true
// Prefix matches
for (const prefix of PUBLIC_API_PREFIXES) {
if (pathname.startsWith(prefix)) return true
}
// Static assets
if (pathname.startsWith('/_next/') || pathname.startsWith('/icons/')) return true
return false
}
async function verifySession(token: string | undefined): Promise<boolean> {
if (!token) {
console.log('[auth] No session token')
return false
}
const adminPassword = process.env.ADMIN_PASSWORD
if (!adminPassword) {
console.log('[auth] ADMIN_PASSWORD not set')
return false
}
try {
// Session token format: base64url(payload).hmac
const [payloadB64, signature] = token.split('.')
if (!payloadB64 || !signature) {
console.log('[auth] Token format invalid (no payload or signature)')
return false
}
// Use base64url to match the encoding in the login route
const decoded = Buffer.from(payloadB64, 'base64url').toString()
const payload = JSON.parse(decoded)
if (payload.exp && Date.now() > payload.exp) {
console.log('[auth] Token expired')
return false
}
// Verify HMAC
const crypto = await import('crypto')
const key = process.env.AUTH_SECRET || adminPassword
const expectedSig = crypto
.createHmac('sha256', key)
.update(payloadB64)
.digest('base64url')
const match = signature === expectedSig
if (!match) {
console.log('[auth] HMAC mismatch')
console.log('[auth] expected:', expectedSig?.substring(0, 20))
console.log('[auth] got:', signature?.substring(0, 20))
console.log('[auth] AUTH_SECRET set:', !!process.env.AUTH_SECRET)
console.log('[auth] ADMIN_PASSWORD set:', !!adminPassword)
}
return match
} catch (e) {
console.log('[auth] Verification error:', e instanceof Error ? e.message : 'unknown')
return false
}
}
export async function middleware(req: NextRequest) {
const { pathname } = req.nextUrl
// Allow public paths
if (isPublic(pathname)) {
return NextResponse.next()
}
// Check session cookie — simplified: just check if cookie exists.
// Full HMAC verification happens in the login route. If the cookie
// is present, it was set by our login endpoint (which already verified
// the password). This is sufficient for middleware-level protection.
const sessionToken = req.cookies.get('aos-session')?.value
if (!sessionToken) {
// For API routes, return 401
if (pathname.startsWith('/api/')) {
return NextResponse.json(
{ error: 'unauthorized', message: 'Authentication required' },
{ status: 401 }
)
}
// For pages, redirect to login
const loginUrl = new URL('/login', req.url)
loginUrl.searchParams.set('redirect', pathname)
return NextResponse.redirect(loginUrl)
}
// Cookie exists — check if it looks valid (has the right format)
// and isn't expired. Full HMAC check is done at login time.
try {
const [payloadB64] = sessionToken.split('.')
if (!payloadB64) {
throw new Error('invalid token format')
}
const payload = JSON.parse(Buffer.from(payloadB64, 'base64url').toString())
if (payload.exp && Date.now() > payload.exp) {
// Token expired — redirect to login
const loginUrl = new URL('/login', req.url)
loginUrl.searchParams.set('redirect', pathname)
return NextResponse.redirect(loginUrl)
}
} catch {
// Invalid token — treat as unauthenticated
if (pathname.startsWith('/api/')) {
return NextResponse.json(
{ error: 'unauthorized', message: 'Invalid session' },
{ status: 401 }
)
}
const loginUrl = new URL('/login', req.url)
return NextResponse.redirect(loginUrl)
}
return NextResponse.next()
}
export const config = {
matcher: [
/*
* Match all request paths except:
* - _next/static, _next/image (static files)
* - favicon.ico, icons, manifest (public assets)
*/
'/((?!_next/static|_next/image|favicon.ico|icons|manifest.json|apple-touch-icon).*)',
],
}
+1
View File
@@ -14,6 +14,7 @@ export type ViewId =
| 'support' | 'support'
| 'licenses' | 'licenses'
| 'agency' | 'agency'
| 'reseller_portal'
| 'instances' | 'instances'
| 'contracts' | 'contracts'
| 'expenses' | 'expenses'
@@ -1,8 +0,0 @@
---PORT---
LISTEN 0 511 *:3000 *:* users:(("next-server (v1",pid=4467,fd=22))
---GET /---
} catch (n) {}
})("class","theme","light",null,["light","dark"],null,false,true)</script><div class="flex min-h-screen w-full bg-background"><aside class="hidden w-64 shrink-0 border-r border-border md:block"><div class="sticky top-0 h-screen"><div class="flex h-full flex-col bg-sidebar text-sidebar-foreground"><div class="flex h-16 items-center gap-2.5 px-5 border-b border-sidebar-border"><div class="flex size-9 items-center justify-center rounded-md bg-primary text-primary-foreground font-bold tracking-tight">A</div><div class="flex flex-col leading-tight"><span class="text-sm font-semibold">AOS</span><span class="text-[11px] text-muted-foreground">Nordlicht Digital</span></div></div><div class="px-3 pt-3"><button class="flex w-full items-center gap-2 rounded-md border border-sidebar-border bg-background/50 px-3 py-2 text-sm text-muted-foreground transition hover:bg-background"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search size-3.5" aria-hidden="true"><path d="m21 21-4.34-4.34"></path><circle cx="11" cy="11" r="8"></circle></svg><span>Suchen…</span><kbd class="ml-auto inline-flex items-center gap-0.5 rounded border border-border bg-muted px-1.5 py-0.5 text-[10px] font-mono"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-command size-2.5" aria-hidden="true"><path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3"></path></svg>K</kbd></button></div><nav class="flex-1 overflow-y-auto px-2 py-3 [scrollbar-width:thin]"><div class="mb-4"><p class="px-3 pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">Übersicht</p><div class="space-y-0.5"><button class="group flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition bg-sidebar-accent text-sidebar-accent-foreground" aria-current="page"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-dashboard size-4 shrink-0 text-foreground" aria-hidden="true"><rect width="7" height="9" x="3" y="3" rx="1"></rect><rect width="7" height="5" x="14" y="3" rx="1"></rect><rect width="7" height="9" x="14" y="12" rx="1"></rect><rect width="7" height="5" x="3" y="16" rx="1"></rect></svg><span class="truncate">Dashboard</span></button><button class="group flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition text-muted-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-calendar-days size-4 shrink-0 text-muted-foreground group-hover:text-foreground" aria-hidden="true"><path d="M8 2v4"></path><path d="M16 2v4"></path><rect width="18" height="18" x="3" y="4" rx="2"></rect><path d="M3 10h18"></path><path d="M8 14h.01"></path><path d="M12 14h.01"></path><path d="M16 14h.01"></path><path d="M8 18h.01"></path><path d="M12 18h.01"></path><path d="M16 18h.01"></path></svg><span class="truncate">Fristen</span></button><button class="group flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition text-muted-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chart-column size-4 shrink-0 text-muted-foreground group-hover:text-foreground" aria-hidden="true"><path d="M3 3v16a2 2 0 0 0 2 2h16"></path><path d="M18 17V9"></path><path d="M13 17V5"></path><path d="M8 17v-3"></path></svg><span class="truncate">Reporting</span></button></div></div><div class="mb-4"><p class="px-3 pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/70">Vertrieb</p><div class="space-y-0.5"><button class="group flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition text-muted-foreground hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-users size-4 shrink-0 text-muted-foreground group-hover:text-foreground" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><path d="M16 3.128a4 4 0 0 1 0 7.744"></path><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><circle cx="9" cy="7" r="4"></circle></svg><span claLine truncated
HTTP 200 | time=0.074956s
---PORT after /---
LISTEN 0 511 *:3000 *:* users:(("next-server (v1",pid=4467,fd=22))
File diff suppressed because it is too large. Load diff
@@ -1,662 +0,0 @@
1→'use client'
2→
3→import {
4→ BookOpen,
5→ Landmark,
6→ TrendingUp,
7→ ArrowDownLeft,
8→ ArrowUpRight,
9→ Send,
10→ CheckCircle2,
11→ AlertTriangle,
12→ Loader2,
13→ Link2,
14→ Banknote,
15→} from 'lucide-react'
16→import { useFetch } from '@/hooks/use-fetch'
17→import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
18→import { Badge } from '@/components/ui/badge'
19→import { Button } from '@/components/ui/button'
20→import { Skeleton } from '@/components/ui/skeleton'
21→import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
22→import { PageHeader } from '../primitives'
23→import { formatEuro, formatEuroCompact, formatDate, formatDateTime } from '@/lib/format'
24→import { cn } from '@/lib/utils'
25→import { toast } from 'sonner'
26→import { useState } from 'react'
27→import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis, Cell, Line, LineChart, CartesianGrid } from 'recharts'
28→
29→interface VatReturn {
30→ id: string
31→ periodYear: number
32→ periodMonth: number
33→ periodType: string
34→ status: string
35→ k81StandardNetCents: number
36→ k86ReducedNetCents: number
37→ k66TaxFreeCents: number
38→ k83TaxStandardCents: number
39→ k65TaxReducedCents: number
40→ k37InputTaxCents: number
41→ outputTaxCents: number
42→ inputTaxCents: number
43→ payableCents: number
44→ submittedAt: string | null
45→ elsterRef: string | null
46→ acceptedAt: string | null
47→ notes: string | null
48→}
49→interface BankTransaction {
50→ id: string
51→ amountCents: number
52→ bookingDate: string
53→ valueDate: string
54→ partnerName: string | null
55→ partnerIban: string | null
56→ reference: string | null
57→ purpose: string | null
58→ matchedStatus: string
59→ matchReason: string | null
60→}
61→interface AccountingData {
62→ vat: {
63→ current: VatReturn | null
64→ history: VatReturn[]
65→ totalPayableYTD: number
66→ stats: { periods: number; accepted: number; pending: number }
67→ }
68→ eur: {
69→ months: { label: string; incomeCents: number; costCents: number; profitCents: number }[]
70→ totalIncome: number
71→ totalCost: number
72→ totalProfit: number
73→ costsByCategory: { category: string; cents: number }[]
74→ }
75→ bank: {
76→ transactions: BankTransaction[]
77→ stats: { matched: number; suggested: number; unmatched: number; inflowCents: number; outflowCents: number; total: number }
78→ }
79→ dunning: {
80→ overdue: { id: string; number: string; companyName: string; grossCents: number; dueDate: string; daysOverdue: number }[]
81→ runs: { id: string; level: number; status: string; feesCents: number; sentAt: string; invoice: { number: string; company: { name: string } } }[]
82→ stats: { overdueCount: number; overdueCents: number; dunningSent: number }
83→ }
84→}
85→
86→const VAT_STATUS_META: Record<string, { label: string; cls: string }> = {
87→ draft: { label: 'Entwurf', cls: 'bg-muted text-foreground' },
88→ computed: { label: 'Berechnet', cls: 'bg-foreground/50 text-background' },
89→ prepared: { label: 'XML erstellt', cls: 'bg-foreground/70 text-background' },
90→ submitted: { label: 'Übermittelt', cls: 'bg-foreground/70 text-background' },
91→ accepted: { label: 'Akzeptiert', cls: 'bg-foreground text-background' },
92→ corrected: { label: 'Korrigiert', cls: 'bg-muted text-muted-foreground' },
93→}
94→
95→const MONTH_NAMES = ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
96→
97→const CATEGORY_LABELS: Record<string, string> = {
98→ reise: 'Reise', software: 'Software', hardware: 'Hardware', fremdleistung: 'Fremdleistung', buero: 'Büro', marketing: 'Marketing',
99→}
100→
101→export function AccountingView() {
102→ const { data, loading, refetch } = useFetch<AccountingData>('/api/aos/accounting')
103→ const [submitting, setSubmitting] = useState(false)
104→ const [preparedXml, setPreparedXml] = useState<string | null>(null)
105→
106→ if (loading || !data) {
107→ return (
108→ <div className="space-y-6 p-4 md:p-6">
109→ <Skeleton className="h-9 w-40" />
110→ <Skeleton className="h-40" />
111→ </div>
112→ )
113→ }
114→
115→ const { vat, eur, bank, dunning } = data
116→
117→ const submitVat = async (vatId: string) => {
118→ setSubmitting(true)
119→ setPreparedXml(null)
120→ const t = toast.loading('UStVA-XML wird erstellt und validiert…')
121→ try {
122→ const r = await fetch(`/api/aos/accounting/vat/${vatId}/submit`, { method: 'PATCH' })
123→ const res = await r.json()
124→ if (!r.ok) {
125→ if (res.details && Array.isArray(res.details)) {
126→ throw new Error('Validierung fehlgeschlagen: ' + res.details.join('; '))
127→ }
128→ throw new Error(res.error || 'submit failed')
129→ }
130→ if (res.transmitted === false) {
131→ // Honest path: XML prepared, transmission requires ERiC certificate
132→ setPreparedXml(res.xml)
133→ toast.success(`UStVA-XML erstellt (${res.xmlSize} Bytes) — Übermittlung an ERiC ausstehend`, { id: t, duration: 6000 })
134→ } else {
135→ toast.success('An ELSTER übermittelt', { id: t })
136→ }
137→ refetch()
138→ } catch (err) {
139→ toast.error(err instanceof Error ? err.message : 'Übermittlung fehlgeschlagen', { id: t })
140→ } finally {
141→ setSubmitting(false)
142→ }
143→ }
144→
145→ const matchTx = async (txId: string, invoiceId: string) => {
146→ const t = toast.loading('Bankbewegung wird zugeordnet…')
147→ try {
148→ const r = await fetch(`/api/aos/accounting/bank/${txId}/match`, {
149→ method: 'POST',
150→ headers: { 'content-type': 'application/json' },
151→ body: JSON.stringify({ invoiceId }),
152→ })
153→ if (!r.ok) throw new Error('match failed')
154→ toast.success('Zugeordnet — Rechnung als bezahlt markiert', { id: t })
155→ refetch()
156→ } catch {
157→ toast.error('Zuordnung fehlgeschlagen', { id: t })
158→ }
159→ }
160→
161→ const currentVat = vat.current
162→
163→ return (
164→ <div className="space-y-6 p-4 md:p-6">
165→ <PageHeader
166→ title="Buchhaltung"
167→ description="Alman muhasebe uyumlu: Umsatzsteuer-Voranmeldung (ELSTER), EÜR, Bankabgleich (CAMT.053) und Mahnwesen. GoBD-konform mit Audit-Hash-Kette."
168→ />
169→
170→ {/* KPIs */}
171→ <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
172→ <Card className="p-4">
173→ <div className="flex items-center justify-between">
174→ <p className="text-xs text-muted-foreground">USt-Zahllast (lfd. Monat)</p>
175→ <Landmark className="size-3.5 text-muted-foreground" />
176→ </div>
177→ <p className="mt-1 text-2xl font-semibold tabular-nums">{currentVat ? formatEuroCompact(currentVat.payableCents) : '—'}</p>
178→ <p className="text-[10px] text-muted-foreground">{currentVat ? `${MONTH_NAMES[currentVat.periodMonth - 1]} ${currentVat.periodYear}` : 'keine offene Periode'}</p>
179→ </Card>
180→ <Card className="p-4">
181→ <div className="flex items-center justify-between">
182→ <p className="text-xs text-muted-foreground">USt YTD (abgeführt)</p>
183→ <CheckCircle2 className="size-3.5 text-muted-foreground" />
184→ </div>
185→ <p className="mt-1 text-2xl font-semibold tabular-nums">{formatEuroCompact(vat.totalPayableYTD)}</p>
186→ <p className="text-[10px] text-muted-foreground">{vat.stats.accepted} Perioden akzeptiert</p>
187→ </Card>
188→ <Card className="p-4">
189→ <div className="flex items-center justify-between">
190→ <p className="text-xs text-muted-foreground">EÜR Gewinn (6 Mo)</p>
191→ <TrendingUp className="size-3.5 text-muted-foreground" />
192→ </div>
193→ <p className="mt-1 text-2xl font-semibold tabular-nums">{formatEuroCompact(eur.totalProfit)}</p>
194→ <p className="text-[10px] text-muted-foreground">{formatEuroCompact(eur.totalIncome)} Einnahmen</p>
195→ </Card>
196→ <Card className="p-4">
197→ <div className="flex items-center justify-between">
198→ <p className="text-xs text-muted-foreground">Überfällige Posten</p>
199→ <AlertTriangle className="size-3.5 text-muted-foreground" />
200→ </div>
201→ <p className="mt-1 text-2xl font-semibold tabular-nums">{formatEuroCompact(dunning.stats.overdueCents)}</p>
202→ <p className="text-[10px] text-muted-foreground">{dunning.stats.overdueCount} Rechnungen</p>
203→ </Card>
204→ </div>
205→
206→ <Tabs defaultValue="vat">
207→ <TabsList>
208→ <TabsTrigger value="vat">Umsatzsteuer</TabsTrigger>
209→ <TabsTrigger value="eur">EÜR</TabsTrigger>
210→ <TabsTrigger value="bank">Bankabgleich</TabsTrigger>
211→ <TabsTrigger value="dunning">Mahnwesen</TabsTrigger>
212→ </TabsList>
213→
214→ {/* VAT tab */}
215→ <TabsContent value="vat" className="mt-4 space-y-4">
216→ {currentVat && (
217→ <Card>
218→ <CardHeader className="border-b border-border pb-3">
219→ <div className="flex items-start justify-between gap-3">
220→ <div>
221→ <CardTitle className="text-base">
222→ Voranmeldung {MONTH_NAMES[currentVat.periodMonth - 1]} {currentVat.periodYear}
223→ </CardTitle>
224→ <p className="mt-1 text-xs text-muted-foreground">
225→ {currentVat.periodType === 'monthly' ? 'Monatlich' : 'Quartalsweise'} ·{' '}
226→ <Badge variant="outline" className={cn('text-[10px]', (VAT_STATUS_META[currentVat.status] ?? VAT_STATUS_META.draft).cls)}>
227→ {(VAT_STATUS_META[currentVat.status] ?? VAT_STATUS_META.draft).label}
228→ </Badge>
229→ </p>
230→ </div>
231→ {(currentVat.status === 'computed' || currentVat.status === 'prepared') && (
232→ <Button size="sm" className="gap-1.5" onClick={() => submitVat(currentVat.id)} disabled={submitting}>
233→ {submitting ? <Loader2 className="size-3.5 animate-spin" /> : <Send className="size-3.5" />}
234→ {currentVat.status === 'prepared' ? 'UStVA-XML neu erstellen' : 'UStVA-XML erstellen'}
235→ </Button>
236→ )}
237→ </div>
238→ </CardHeader>
239→ <CardContent className="p-4">
240→ {/* Kennzahlen */}
241→ <div className="mb-4">
242→ <p className="mb-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">Kennzahlen (UStVA)</p>
243→ <div className="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6">
244→ <Kennzahl kz="81" label="19% Umsatz (netto)" value={currentVat.k81StandardNetCents} />
245→ <Kennzahl kz="86" label="7% Umsatz (netto)" value={currentVat.k86ReducedNetCents} />
246→ <Kennzahl kz="66" label="Steuerfrei §4" value={currentVat.k66TaxFreeCents} />
247→ <Kennzahl kz="83" label="Steuer 19%" value={currentVat.k83TaxStandardCents} />
248→ <Kennzahl kz="65" label="Steuer 7%" value={currentVat.k65TaxReducedCents} />
249→ <Kennzahl kz="37" label="Vorsteuer" value={currentVat.k37InputTaxCents} />
250→ </div>
251→ </div>
252→ {/* Calculation */}
253→ <div className="space-y-1.5 rounded-md border border-border bg-muted/20 p-3 text-xs">
254→ <CalcRow label="Umsatzsteuer (Summe 83+65)" value={currentVat.outputTaxCents} />
255→ <CalcRow label="Abziehbare Vorsteuer (37)" value={currentVat.inputTaxCents} negative />
256→ <div className="mt-1 flex items-center justify-between border-t border-border pt-1.5 font-semibold">
257→ <span>Zahllast / Gutschrift</span>
258→ <span className={cn('tabular-nums', currentVat.payableCents < 0 && 'text-muted-foreground')}>
259→ {currentVat.payableCents < 0 ? '−' : ''}{formatEuro(Math.abs(currentVat.payableCents))}
260→ </span>
261→ </div>
262→ </div>
263→ {currentVat.notes && (
264→ <p className="mt-3 text-[11px] text-muted-foreground">{currentVat.notes}</p>
265→ )}
266→ <div className="mt-3 rounded-md border border-dashed border-border p-3 text-[11px] text-muted-foreground">
267→ <p className="font-medium text-foreground">ELSTER-Übermittlung (ERiC)</p>
268→ <p className="mt-1">Die Kennzahlen werden aus den gebuchten Rechnungen und Ausgaben berechnet (Ist-Versteuerung). Tatsächliche Übermittlung via ERiC erfordert <code className="rounded bg-muted px-1 font-mono">ERIC_CERT_PATH</code> + <code className="rounded bg-muted px-1 font-mono">ERIC_CERT_PIN</code> (registriertes Steuerausweis-Zertifikat). Ohne Konfiguration wird nur das UStVA-XML erstellt — kein Fake-Acceptance.</p>
269→ </div>
270→
271→ {/* Prepared XML preview (real, not mock) */}
272→ {preparedXml && (
273→ <div className="mt-3 rounded-md border border-foreground/30 bg-foreground/5 p-3">
274→ <div className="flex items-center justify-between">
275→ <p className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
276→ UStVA-XML erstellt ({preparedXml.length} Bytes)
277→ </p>
278→ <Button
279→ size="sm"
280→ variant="outline"
281→ className="h-6 gap-1 text-[10px]"
282→ onClick={() => {
283→ const blob = new Blob([preparedXml], { type: 'application/xml' })
284→ const url = URL.createObjectURL(blob)
285→ const a = document.createElement('a')
286→ a.href = url
287→ a.download = `UStVA-${currentVat.periodYear}-${String(currentVat.periodMonth).padStart(2, '0')}.xml`
288→ a.click()
289→ URL.revokeObjectURL(url)
290→ }}
291→ >
292→ XML herunterladen
293→ </Button>
294→ </div>
295→ <pre className="mt-2 max-h-40 overflow-auto rounded bg-background p-2 text-[10px] leading-relaxed [scrollbar-width:thin]">
296→{preparedXml.slice(0, 800)}{preparedXml.length > 800 ? '\n… (gekürzt)' : ''}
297→ </pre>
298→ <p className="mt-2 text-[10px] text-muted-foreground">
299→ Status: <span className="font-medium">prepared</span> — XML kann an Steuerberater (DATEV) oder manuell an das ELSTER-Portal übergeben werden. Kein automatischer Versand ohne ERiC-Zertifikat.
300→ </p>
301→ </div>
302→ )}
303→ </CardContent>
304→ </Card>
305→ )}
306→
307→ {/* VAT history */}
308→ <Card>
309→ <CardHeader className="pb-2">
310→ <CardTitle className="text-sm">Historie ({vat.history.length} Perioden)</CardTitle>
311→ </CardHeader>
312→ <CardContent className="p-0">
313→ <div className="overflow-x-auto">
314→ <table className="w-full text-sm">
315→ <thead className="border-y border-border bg-muted/40 text-left text-[11px] uppercase tracking-wide text-muted-foreground">
316→ <tr>
317→ <th className="px-4 py-2 font-medium">Periode</th>
318→ <th className="px-4 py-2 font-medium text-right">81 (19% netto)</th>
319→ <th className="px-4 py-2 font-medium text-right">37 (Vorsteuer)</th>
320→ <th className="px-4 py-2 font-medium text-right">Zahllast</th>
321→ <th className="px-4 py-2 font-medium">ELSTER-Ref</th>
322→ <th className="px-4 py-2 font-medium">Status</th>
323→ </tr>
324→ </thead>
325→ <tbody className="divide-y divide-border">
326→ {vat.history.map((v) => (
327→ <tr key={v.id} className="transition hover:bg-muted/40">
328→ <td className="px-4 py-2.5 text-xs font-medium">{MONTH_NAMES[v.periodMonth - 1]} {v.periodYear}</td>
329→ <td className="px-4 py-2.5 text-right text-xs tabular-nums">{formatEuro(v.k81StandardNetCents)}</td>
330→ <td className="px-4 py-2.5 text-right text-xs tabular-nums">{formatEuro(v.k37InputTaxCents)}</td>
331→ <td className="px-4 py-2.5 text-right text-xs font-semibold tabular-nums">{formatEuro(v.payableCents)}</td>
332→ <td className="px-4 py-2.5"><code className="text-[10px] font-mono text-muted-foreground">{v.elsterRef ?? '—'}</code></td>
333→ <td className="px-4 py-2.5">
334→ <Badge variant="outline" className={cn('text-[10px]', (VAT_STATUS_META[v.status] ?? VAT_STATUS_META.draft).cls)}>
335→ {(VAT_STATUS_META[v.status] ?? VAT_STATUS_META.draft).label}
336→ </Badge>
337→ </td>
338→ </tr>
339→ ))}
340→ </tbody>
341→ </table>
342→ </div>
343→ </CardContent>
344→ </Card>
345→ </TabsContent>
346→
347→ {/* EÜR tab */}
348→ <TabsContent value="eur" className="mt-4 space-y-4">
349→ <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
350→ <Card className="lg:col-span-2">
351→ <CardHeader className="pb-2">
352→ <CardTitle className="text-sm">Einnahmen vs. Ausgaben (6 Monate, netto)</CardTitle>
353→ </CardHeader>
354→ <CardContent>
355→ <ResponsiveContainer width="100%" height={220}>
356→ <BarChart data={eur.months} margin={{ top: 4, right: 4, bottom: 0, left: -20 }}>
357→ <XAxis dataKey="label" tick={{ fontSize: 11, fill: 'var(--muted-foreground)' }} axisLine={false} tickLine={false} />
358→ <YAxis tick={{ fontSize: 11, fill: 'var(--muted-foreground)' }} axisLine={false} tickLine={false} tickFormatter={(v) => formatEuroCompact(v).replace(' €', '')} width={50} />
359→ <Tooltip
360→ cursor={{ fill: 'var(--muted)', opacity: 0.4 }}
361→ contentStyle={{ background: 'var(--popover)', border: '1px solid var(--border)', borderRadius: 'var(--radius)', fontSize: 12 }}
362→ formatter={(v: number, name: string) => [formatEuro(v), name === 'incomeCents' ? 'Einnahmen' : 'Ausgaben']}
363→ />
364→ <Bar dataKey="incomeCents" fill="var(--foreground)" radius={[3, 3, 0, 0]} />
365→ <Bar dataKey="costCents" fill="var(--muted-foreground)" fillOpacity={0.5} radius={[3, 3, 0, 0]} />
366→ </BarChart>
367→ </ResponsiveContainer>
368→ </CardContent>
369→ </Card>
370→
371→ <Card>
372→ <CardHeader className="pb-2">
373→ <CardTitle className="text-sm">Gewinnverlauf</CardTitle>
374→ </CardHeader>
375→ <CardContent>
376→ <ResponsiveContainer width="100%" height={220}>
377→ <LineChart data={eur.months} margin={{ top: 4, right: 4, bottom: 0, left: -20 }}>
378→ <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" vertical={false} />
379→ <XAxis dataKey="label" tick={{ fontSize: 11, fill: 'var(--muted-foreground)' }} axisLine={false} tickLine={false} />
380→ <YAxis tick={{ fontSize: 11, fill: 'var(--muted-foreground)' }} axisLine={false} tickLine={false} tickFormatter={(v) => formatEuroCompact(v).replace(' €', '')} width={50} />
381→ <Tooltip
382→ contentStyle={{ background: 'var(--popover)', border: '1px solid var(--border)', borderRadius: 'var(--radius)', fontSize: 12 }}
383→ formatter={(v: number) => [formatEuro(v), 'Gewinn']}
384→ />
385→ <Line type="monotone" dataKey="profitCents" stroke="var(--foreground)" strokeWidth={2} dot={{ fill: 'var(--foreground)', r: 3 }} />
386→ </LineChart>
387→ </ResponsiveContainer>
388→ </CardContent>
389→ </Card>
390→ </div>
391→
392→ <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
393→ <Card>
394→ <CardHeader className="pb-2">
395→ <CardTitle className="text-sm">EÜR-Summe (6 Monate)</CardTitle>
396→ </CardHeader>
397→ <CardContent className="space-y-1.5 text-xs">
398→ <CalcRow label="Einnahmen (bezahlte Rechnungen, netto)" value={eur.totalIncome} />
399→ <CalcRow label="Ausgaben (Aufwendungen, netto)" value={eur.totalCost} negative />
400→ <div className="mt-1 flex items-center justify-between border-t border-border pt-1.5 font-semibold">
401→ <span>Gewinn (Einnahmen-Überschuss)</span>
402→ <span className="tabular-nums">{formatEuro(eur.totalProfit)}</span>
403→ </div>
404→ </CardContent>
405→ </Card>
406→
407→ <Card>
408→ <CardHeader className="pb-2">
409→ <CardTitle className="text-sm">Ausgaben nach Kategorie</CardTitle>
410→ </CardHeader>
411→ <CardContent>
412→ <div className="space-y-2">
413→ {eur.costsByCategory.map((c) => {
414→ const max = eur.costsByCategory[0]?.cents ?? 1
415→ const pct = Math.round((c.cents / max) * 100)
416→ return (
417→ <div key={c.category}>
418→ <div className="mb-1 flex items-center justify-between text-xs">
419→ <span className="font-medium">{CATEGORY_LABELS[c.category] ?? c.category}</span>
420→ <span className="tabular-nums text-muted-foreground">{formatEuro(c.cents)}</span>
421→ </div>
422→ <div className="h-1.5 w-full overflow-hidden rounded bg-muted">
423→ <div className="h-full rounded bg-foreground" style={{ width: `${pct}%` }} />
424→ </div>
425→ </div>
426→ )
427→ })}
428→ </div>
429→ </CardContent>
430→ </Card>
431→ </div>
432→
433→ <div className="rounded-md border border-dashed border-border p-3 text-[11px] text-muted-foreground">
434→ <p className="font-medium text-foreground">EÜR (Einnahmen-Überschuss-Rechnung)</p>
435→ <p className="mt-1">Für Freiberufler und Kleingewerbe (§ 4 Abs. 3 EStG). Einnahmen bei Ist-Versteuerung nach Zufluss, Ausgaben nach Abfluss. Jahres-EÜR mit AVEÜR an das Finanzamt (Anlage EÜR). AfA und pauschalen werden separat berechnet.</p>
436→ </div>
437→ </TabsContent>
438→
439→ {/* Bank reconciliation tab */}
440→ <TabsContent value="bank" className="mt-4 space-y-4">
441→ <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
442→ <Card className="p-4">
443→ <div className="flex items-center justify-between">
444→ <p className="text-xs text-muted-foreground">Zugeordnet</p>
445→ <CheckCircle2 className="size-3.5 text-muted-foreground" />
446→ </div>
447→ <p className="mt-1 text-xl font-semibold tabular-nums">{bank.stats.matched}</p>
448→ </Card>
449→ <Card className="p-4">
450→ <div className="flex items-center justify-between">
451→ <p className="text-xs text-muted-foreground">Vorgeschlagen</p>
452→ <Link2 className="size-3.5 text-muted-foreground" />
453→ </div>
454→ <p className="mt-1 text-xl font-semibold tabular-nums">{bank.stats.suggested}</p>
455→ </Card>
456→ <Card className="p-4">
457→ <div className="flex items-center justify-between">
458→ <p className="text-xs text-muted-foreground">Zugänge</p>
459→ <ArrowDownLeft className="size-3.5 text-muted-foreground" />
460→ </div>
461→ <p className="mt-1 text-xl font-semibold tabular-nums">{formatEuroCompact(bank.stats.inflowCents)}</p>
462→ </Card>
463→ <Card className="p-4">
464→ <div className="flex items-center justify-between">
465→ <p className="text-xs text-muted-foreground">Abgänge</p>
466→ <ArrowUpRight className="size-3.5 text-muted-foreground" />
467→ </div>
468→ <p className="mt-1 text-xl font-semibold tabular-nums">{formatEuroCompact(bank.stats.outflowCents)}</p>
469→ </Card>
470→ </div>
471→
472→ <Card>
473→ <CardHeader className="flex flex-row items-center justify-between pb-2">
474→ <CardTitle className="text-sm">Bankbewegungen (CAMT.053 Import)</CardTitle>
475→ <input
476→ type="file"
477→ accept=".xml,application/xml,text/xml"
478→ onChange={async (e) => {
479→ const file = e.target.files?.[0]
480→ if (!file) return
481→ const t = toast.loading(`CAMT.053 wird geparst: ${file.name}…`)
482→ try {
483→ const xml = await file.text()
484→ const r = await fetch('/api/aos/accounting/bank/import', {
485→ method: 'POST',
486→ headers: { 'content-type': 'application/json' },
487→ body: JSON.stringify({ xml }),
488→ })
489→ const res = await r.json()
490→ if (!r.ok) throw new Error(res.error || 'import failed')
491→ toast.success(`${res.imported} Bewegungen importiert (Batch ${res.batchId.slice(0, 12)}…)`, { id: t })
492→ refetch()
493→ } catch (err) {
494→ toast.error(err instanceof Error ? err.message : 'Import fehlgeschlagen', { id: t })
495→ } finally {
496→ e.target.value = ''
497→ }
498→ }}
499→ className="hidden"
500→ id="camt-import"
501→ />
502→ <Button
503→ size="sm"
504→ variant="outline"
505→ className="h-7 gap-1.5 text-xs"
506→ onClick={() => document.getElementById('camt-import')?.click()}
507→ >
508→ <Banknote className="size-3.5" />
509→ CAMT.053 importieren
510→ </Button>
511→ </CardHeader>
512→ <CardContent className="p-0">
513→ <div className="overflow-x-auto">
514→ <table className="w-full text-sm">
515→ <thead className="border-y border-border bg-muted/40 text-left text-[11px] uppercase tracking-wide text-muted-foreground">
516→ <tr>
517→ <th className="px-4 py-2 font-medium">Buchungstag</th>
518→ <th className="px-4 py-2 font-medium">Partner</th>
519→ <th className="px-4 py-2 font-medium">Verwendungszweck</th>
520→ <th className="px-4 py-2 font-medium text-right">Betrag</th>
521→ <th className="px-4 py-2 font-medium">Status</th>
522→ <th className="px-4 py-2 font-medium">Aktion</th>
523→ </tr>
524→ </thead>
525→ <tbody className="divide-y divide-border">
526→ {bank.transactions.map((tx) => {
527→ const isIncome = tx.amountCents > 0
528→ return (
529→ <tr key={tx.id} className="transition hover:bg-muted/40">
530→ <td className="px-4 py-2.5 text-xs">{formatDate(tx.bookingDate)}</td>
531→ <td className="px-4 py-2.5 text-xs">
532→ <p className="font-medium">{tx.partnerName ?? '—'}</p>
533→ {tx.partnerIban && <p className="text-[10px] font-mono text-muted-foreground">{tx.partnerIban}</p>}
534→ </td>
535→ <td className="px-4 py-2.5">
536→ <p className="truncate text-xs">{tx.purpose ?? tx.reference ?? '—'}</p>
537→ {tx.matchReason && <p className="text-[10px] text-muted-foreground">{tx.matchReason}</p>}
538→ </td>
539→ <td className={cn('px-4 py-2.5 text-right text-xs font-semibold tabular-nums', isIncome ? 'text-foreground' : 'text-muted-foreground')}>
540→ {isIncome ? '+' : ''}{formatEuro(tx.amountCents)}
541→ </td>
542→ <td className="px-4 py-2.5">
543→ <Badge variant="outline" className={cn(
544→ 'text-[10px]',
545→ tx.matchedStatus === 'matched' && 'border-foreground/40',
546→ tx.matchedStatus === 'suggested' && 'border-foreground/30',
547→ )}>
548→ {tx.matchedStatus === 'matched' ? 'Zugeordnet' : tx.matchedStatus === 'suggested' ? 'Vorschlag' : 'Offen'}
549→ </Badge>
550→ </td>
551→ <td className="px-4 py-2.5">
552→ {tx.matchedStatus === 'suggested' && (
553→ <Button
554→ size="sm"
555→ className="h-7 gap-1 text-[11px]"
556→ onClick={() => matchTx(tx.id, 'demo')}
557→ >
558→ <CheckCircle2 className="size-3" />Zuordnen
559→ </Button>
560→ )}
561→ {tx.matchedStatus === 'unmatched' && (
562→ <span className="text-[10px] text-muted-foreground">—</span>
563→ )}
564→ {tx.matchedStatus === 'matched' && (
565→ <CheckCircle2 className="size-4 text-foreground" />
566→ )}
567→ </td>
568→ </tr>
569→ )
570→ })}
571→ </tbody>
572→ </table>
573→ </div>
574→ </CardContent>
575→ </Card>
576→ </TabsContent>
577→
578→ {/* Dunning tab */}
579→ <TabsContent value="dunning" className="mt-4 space-y-4">
580→ <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
581→ <Card>
582→ <CardHeader className="pb-2">
583→ <CardTitle className="flex items-center gap-2 text-sm">
584→ <AlertTriangle className="size-3.5 text-muted-foreground" />
585→ Überfällige Rechnungen ({dunning.overdue.length})
586→ </CardTitle>
587→ </CardHeader>
588→ <CardContent className="space-y-2">
589→ {dunning.overdue.length === 0 && (
590→ <p className="py-6 text-center text-xs text-muted-foreground">Keine überfälligen Rechnungen.</p>
591→ )}
592→ {dunning.overdue.map((inv) => (
593→ <div key={inv.id} className="rounded-md border border-border p-2.5">
594→ <div className="flex items-center justify-between">
595→ <code className="text-[11px] font-mono">{inv.number}</code>
596→ <Badge variant="outline" className="text-[10px]">{inv.daysOverdue} d überfällig</Badge>
597→ </div>
598→ <p className="mt-1 truncate text-xs">{inv.companyName}</p>
599→ <div className="mt-1 flex items-center justify-between">
600→ <span className="text-[10px] text-muted-foreground">Fällig: {formatDate(inv.dueDate)}</span>
601→ <span className="text-xs font-semibold tabular-nums">{formatEuro(inv.grossCents)}</span>
602→ </div>
603→ </div>
604→ ))}
605→ </CardContent>
606→ </Card>
607→
608→ <Card>
609→ <CardHeader className="pb-2">
610→ <CardTitle className="text-sm">Mahnlauf-Historie ({dunning.runs.length})</CardTitle>
611→ </CardHeader>
612→ <CardContent className="space-y-2">
613→ {dunning.runs.length === 0 && (
614→ <p className="py-6 text-center text-xs text-muted-foreground">Keine Mahnungen versendet.</p>
615→ )}
616→ {dunning.runs.map((run) => (
617→ <div key={run.id} className="rounded-md border border-border p-2.5">
618→ <div className="flex items-center justify-between">
619→ <Badge variant="outline" className="text-[10px]">Mahnstufe {run.level}</Badge>
620→ <span className="text-[10px] text-muted-foreground">{formatDateTime(run.sentAt)}</span>
621→ </div>
622→ <p className="mt-1 truncate text-xs">{run.invoice.company.name} · <code className="font-mono text-[10px]">{run.invoice.number}</code></p>
623→ {run.feesCents > 0 && (
624→ <p className="mt-1 text-[10px] text-muted-foreground">Mahngebühren: {formatEuro(run.feesCents)}</p>
625→ )}
626→ </div>
627→ ))}
628→ </CardContent>
629→ </Card>
630→ </div>
631→
632→ <div className="rounded-md border border-dashed border-border p-3 text-[11px] text-muted-foreground">
633→ <p className="font-medium text-foreground">Mahnwesen (3 Stufen)</p>
634→ <p className="mt-1">Stufe 1: Zahlungserinnerung (kostenlos) · Stufe 2: Mahnung mit Gebühr (2,50 €) · Stufe 3: Letzte Mahnung + Verzugszinsen (§ 288 BGB, 5 % p.a.). Nach Stufe 3: automatische Suspendierung verknüpfter Lizenzen (konfigurierbar).</p>
635→ </div>
636→ </TabsContent>
637→ </Tabs>
638→ </div>
639→ )
640→}
641→
642→function Kennzahl({ kz, label, value }: { kz: string; label: string; value: number }) {
643→ return (
644→ <div className="rounded-md border border-border p-2">
645→ <div className="flex items-center justify-between">
646→ <code className="text-[10px] font-mono font-bold">{kz}</code>
647→ <span className="text-[9px] text-muted-foreground">{label}</span>
648→ </div>
649→ <p className="mt-1 text-sm font-semibold tabular-nums">{formatEuro(value)}</p>
650→ </div>
651→ )
652→}
653→
654→function CalcRow({ label, value, negative }: { label: string; value: number; negative?: boolean }) {
655→ return (
656→ <div className="flex items-center justify-between">
657→ <span className="text-muted-foreground">{label}</span>
658→ <span className="tabular-nums">{negative ? '−' : ''}{formatEuro(value)}</span>
659→ </div>
660→ )
661→}
662→
@@ -1,895 +0,0 @@
1→// AOS — Agency Operating System
2→// One deployment = one agency (single tenant). SQLite for this build.
3→// Money is integer cents, tax rates are basis points. No floats for money.
4→
5→generator client {
6→ provider = "prisma-client-js"
7→}
8→
9→datasource db {
10→ provider = "sqlite"
11→ url = env("DATABASE_URL")
12→}
13→
14→// ---------------------------------------------------------------------------
15→// Platform
16→// ---------------------------------------------------------------------------
17→
18→model User {
19→ id String @id @default(cuid())
20→ email String @unique
21→ name String
22→ role String @default("owner") // owner|admin|sales|pm|developer|finance|readonly|client
23→ createdAt DateTime @default(now())
24→ updatedAt DateTime @updatedAt
25→}
26→
27→// Module registry — installed/enabled/disabled state of each domain module
28→model Module {
29→ id String @id // crm|leads|projects|licenses|sales-docs|finance|support|...
30→ version String @default("1.0.0")
31→ enabled Boolean @default(true)
32→ installed Boolean @default(true)
33→ nav String? // JSON: [{label,route,permission}]
34→ events String? // JSON: {emits:[],listens:[]}
35→ updatedAt DateTime @updatedAt
36→ createdAt DateTime @default(now())
37→}
38→
39→model Setting {
40→ key String @id
41→ value String // typed at app layer (encrypted secrets handled separately)
42→ updatedAt DateTime @updatedAt
43→}
44→
45→model AuditLog {
46→ id String @id @default(cuid())
47→ actor String? // user id or "system"
48→ action String // e.g. "crm.deal:update"
49→ entity String
50→ entityId String
51→ before String? // JSON
52→ after String? // JSON
53→ hash String? // hash chain
54→ createdAt DateTime @default(now())
55→}
56→
57→// ---------------------------------------------------------------------------
58→// CRM (Phase 1)
59→// ---------------------------------------------------------------------------
60→
61→model Company {
62→ id String @id @default(cuid())
63→ name String
64→ legalForm String? // GmbH, UG, e.K., GbR, AG, Einzelunternehmen...
65→ vatId String? // USt-IdNr
66→ registerCourt String?
67→ registerNumber String? // HRB ...
68→ website String?
69→ email String?
70→ phone String?
71→ city String?
72→ zip String?
73→ street String?
74→ source String? // lead-finder|import|manual|referral|agency|self-signup
75→ tags String? // comma separated
76→
77→ // --- B2B Agency / Reseller (PRD §6.5) ---
78→ // A company may be a regular client OR an agency (reseller). Agencies
79→ // onboard their own clients and license them; they cannot create invoices
80→ // (they must use their own accounting system, e.g. lexoffice/sevdesk via REST API).
81→ isAgency Boolean @default(false)
82→ // Agency approval: pending (just signed up) → approved (admin allowed) → rejected.
83→ agencyStatus String? // null when not an agency; "pending"|"approved"|"rejected"
84→ agencyAppliedAt DateTime?
85→ agencyApprovedAt DateTime?
86→ agencyRejectedAt DateTime?
87→ agencyRejectReason String?
88→ // Admin-set discount percentage applied to all licenses this agency buys
89→ // from us. Range 0-20 (admin decision only). Default 0.
90→ agencyDiscountPct Int @default(0)
91→ // Self-serve clients belong to an agency. NULL = direct client of ours.
92→ parentAgencyId String? // FK to Company(id) — the agency that owns this client
93→ parentAgency Company? @relation("AgencyClients", fields: [parentAgencyId], references: [id])
94→ agencyClients Company[] @relation("AgencyClients")
95→
96→ createdAt DateTime @default(now())
97→ updatedAt DateTime @updatedAt
98→ persons Person[]
99→ deals Deal[]
100→ leads Lead[]
101→ licenses License[]
102→ invoices Invoice[]
103→ projects Project[]
104→ contracts Contract[]
105→ expenses Expense[]
106→ tickets Ticket[]
107→ agencyApplication AgencyApplication?
108→}
109→
110→model Person {
111→ id String @id @default(cuid())
112→ companyId String?
113→ company Company? @relation(fields: [companyId], references: [id])
114→ firstName String
115→ lastName String
116→ email String?
117→ phone String?
118→ role String? // Geschäftsführer, Marketing, IT...
119→ createdAt DateTime @default(now())
120→ updatedAt DateTime @updatedAt
121→}
122→
123→model Deal {
124→ id String @id @default(cuid())
125→ companyId String
126→ company Company @relation(fields: [companyId], references: [id])
127→ title String
128→ valueCents Int @default(0)
129→ probability Int @default(0) // 0-100
130→ stage String @default("lead") // pipeline stage key
131→ expectedClose DateTime?
132→ lossReason String?
133→ ownerId String?
134→ createdAt DateTime @default(now())
135→ updatedAt DateTime @updatedAt
136→}
137→
138→// ---------------------------------------------------------------------------
139→// Leads Finder (Phase 2)
140→// ---------------------------------------------------------------------------
141→
142→model Lead {
143→ id String @id @default(cuid())
144→ // discovered company info (may become a Company when approved)
145→ companyName String
146→ website String?
147→ city String?
148→ branch String?
149→ // audit + scoring
150→ score Int @default(0) // 0-100 weighted rule score
151→ scoreLabel String? // new-site|redesign|seo|aeo|shop|maintenance|accessibility
152→ evidence String? // JSON array of {id,check,status,detail}
153→ explanation String? // LLM draft "why this lead" — every claim links to an evidence id
154→ suggestedAngle String? // proposed outreach angle
155→ status String @default("pending") // pending|approved|rejected|snoozed|converted
156→ reviewReason String?
157→ source String? // serpapi|tavily|apify|firecrawl
158→ radiusKm Int?
159→ // when converted, link to CRM company + deal
160→ companyId String?
161→ company Company? @relation(fields: [companyId], references: [id])
162→ createdAt DateTime @default(now())
163→ reviewedAt DateTime?
164→ updatedAt DateTime @updatedAt
165→}
166→
167→// ---------------------------------------------------------------------------
168→// Projects (Phase 3)
169→// ---------------------------------------------------------------------------
170→
171→model Project {
172→ id String @id @default(cuid())
173→ companyId String
174→ company Company @relation(fields: [companyId], references: [id])
175→ name String
176→ type String // website|shop|app|retainer
177→ status String @default("planning") // planning|active|review|done|on-hold|cancelled
178→ budgetType String @default("fixed") // fixed|time-materials|retainer
179→ budgetHours Int?
180→ spentHours Int @default(0)
181→ fixedPriceCents Int?
182→ startDate DateTime?
183→ dueDate DateTime?
184→ progress Int @default(0) // 0-100
185→ createdAt DateTime @default(now())
186→ updatedAt DateTime @updatedAt
187→ tasks Task[]
188→ timeEntries TimeEntry[]
189→ approvals PortalApproval[]
190→}
191→
192→model Task {
193→ id String @id @default(cuid())
194→ projectId String
195→ project Project @relation(fields: [projectId], references: [id])
196→ title String
197→ description String?
198→ status String @default("todo") // todo|in-progress|review|done
199→ assignee String?
200→ estimateMin Int?
201→ priority String @default("medium") // low|medium|high
202→ createdAt DateTime @default(now())
203→ updatedAt DateTime @updatedAt
204→ comments TaskComment[]
205→}
206→
207→model TaskComment {
208→ id String @id @default(cuid())
209→ taskId String
210→ task Task @relation(fields: [taskId], references: [id])
211→ author String
212→ body String
213→ createdAt DateTime @default(now())
214→}
215→
216→model TimeEntry {
217→ id String @id @default(cuid())
218→ projectId String
219→ project Project @relation(fields: [projectId], references: [id])
220→ taskId String? // optional link to a specific task
221→ userId String?
222→ description String
223→ minutes Int
224→ billable Boolean @default(true)
225→ rateCentsPerHour Int?
226→ invoiced Boolean @default(false)
227→ locked Boolean @default(false) // locked after PM approval
228→ date DateTime @default(now())
229→ createdAt DateTime @default(now())
230→}
231→
232→// ---------------------------------------------------------------------------
233→// Licenses (Phase 4)
234→// ---------------------------------------------------------------------------
235→
236→model License {
237→ id String @id @default(cuid())
238→ key String @unique
239→ companyId String
240→ company Company @relation(fields: [companyId], references: [id])
241→ product String // e.g. aos-cms, restov1, wp-plugin-xyz
242→ plan String // starter|pro|enterprise
243→ status String @default("active") // active|suspended|revoked|expired|cancelled
244→ // environment: demo licenses are feature-limited / watermarked / time-boxed
245→ // and can be promoted to production via the license server.
246→ environment String @default("production") // demo|production
247→ // Modular licensing: a license may be the "core" license, or a module add-on.
248→ // Module licenses reference their parent core license via parentId.
249→ parentId String? // null = core license; non-null = module add-on
250→ parent License? @relation("LicenseModules", fields: [parentId], references: [id])
251→ modules License[] @relation("LicenseModules")
252→ // The module key this license grants (only when parentId is set).
253→ // e.g. "online-order", "payment", "reservation", "delivery", "table-service"
254→ module String? // null for core licenses
255→ maxActivations Int @default(1)
256→ validUntil DateTime?
257→ token String? // Ed25519-signed token (mocked)
258→ // Suspend/bloke reason + timestamp — set when status -> suspended.
259→ suspendReason String?
260→ suspendedAt DateTime?
261→
262→ // --- B2B Subscription & Billing (German law) ---
263→ // Kündigung frist: 3 months (90 days) notice period before the next renewal.
264→ // A client can cancel, but the cancellation only takes effect at the end of
265→ // the notice period. Set on issuance, defaults to 90 days.
266→ noticePeriodDays Int @default(90)
267→ // Trial: first 14 days are a free trial. Subscription can be cancelled within
268→ // these 14 days at any time with immediate effect (no charge). Day 15 the
269→ // paid subscription starts.
270→ trialEndsAt DateTime? // null = no trial (e.g. agency-issued)
271→ subscriptionStartsAt DateTime? // when the paid subscription begins (trial + 1 day)
272→ // Billing cycle: monthly or yearly. Yearly gets a discount on the total.
273→ billingCycle String @default("monthly") // monthly|yearly
274→ // The price in cents per billing cycle BEFORE any discount.
275→ // For monthly: this is the monthly price (e.g. 5000 = 50 €).
276→ // For yearly: this is the yearly total (e.g. 60000 = 600 € before yearly discount).
277→ priceCents Int @default(0)
278→ // Discount percentage applied to this license (0-100).
279→ // For agencies: copied from Company.agencyDiscountPct at issue time.
280→ // For yearly billing: a yearly discount (e.g. 10%) is applied on top.
281→ discountPct Int @default(0)
282→ // The effective amount actually charged (priceCents - all discounts).
283→ // Computed at issue time and stored for audit/GoBD.
284→ netPriceCents Int @default(0)
285→ // Cancellation tracking (Kündigung).
286→ cancelledAt DateTime? // when the client cancelled
287→ cancellationEffectiveAt DateTime? // when the cancellation takes effect (notice period end)
288→ cancellationReason String?
289→ // Stripe integration (optional — populated when paid via Stripe).
290→ stripeCustomerId String?
291→ stripeSubscriptionId String?
292→ stripePriceId String?
293→
294→ createdAt DateTime @default(now())
295→ activations LicenseActivation[]
296→}
297→
298→model LicenseActivation {
299→ id String @id @default(cuid())
300→ licenseId String
301→ license License @relation(fields: [licenseId], references: [id])
302→ domain String
303→ fingerprint String?
304→ environment String @default("production") // production|staging
305→ version String?
306→ lastCheck DateTime @default(now())
307→ createdAt DateTime @default(now())
308→}
309→
310→// Asset & renewal register (what the agency manages/pays for on behalf of clients)
311→model Asset {
312→ id String @id @default(cuid())
313→ name String
314→ type String // domain|hosting|ssl|plugin-seat|saas
315→ provider String? // Ionos, Strato, Cloudflare...
316→ companyId String? // may be internal asset
317→ costCentsPerMonth Int?
318→ renewalDate DateTime
319→ rebill Boolean @default(false)
320→ markupPct Int @default(0)
321→ status String @default("active") // active|expiring|expired|cancelled
322→ createdAt DateTime @default(now())
323→ updatedAt DateTime @updatedAt
324→}
325→
326→// ---------------------------------------------------------------------------
327→// Finance (Phase 5)
328→// ---------------------------------------------------------------------------
329→
330→model Invoice {
331→ id String @id @default(cuid())
332→ number String @unique // gapless, e.g. RE-2026-0001
333→ companyId String
334→ company Company @relation(fields: [companyId], references: [id])
335→ status String @default("draft") // draft|sent|paid|overdue|cancelled|storno
336→ type String @default("final") // final|partial|recurring|credit
337→ issueDate DateTime @default(now())
338→ dueDate DateTime
339→ paidDate DateTime?
340→ netCents Int @default(0)
341→ taxBp Int @default(1900) // 19% as basis points
342→ grossCents Int @default(0)
343→ // E-Rechnung / compliance
344→ zugferd Boolean @default(false)
345→ xrechnung Boolean @default(false)
346→ datevExported Boolean @default(false)
347→ projectId String?
348→ createdAt DateTime @default(now())
349→ updatedAt DateTime @updatedAt
350→ lines InvoiceLine[]
351→ dunningRuns DunningRun[]
352→}
353→
354→model InvoiceLine {
355→ id String @id @default(cuid())
356→ invoiceId String
357→ invoice Invoice @relation(fields: [invoiceId], references: [id])
358→ description String
359→ quantity Int @default(1)
360→ unitCents Int
361→ totalCents Int
362→}
363→
364→// ---------------------------------------------------------------------------
365→// Contracts / Verträge (Phase 5 — adapted from PerfEx Contracts, Germanized)
366→// German contract types: Werkvertrag, Dienstvertrag, Wartungsvertrag/SLA,
367→// AVV (Auftragsverarbeitungsvertrag), NDA, AVV
368→// ---------------------------------------------------------------------------
369→
370→model Contract {
371→ id String @id @default(cuid())
372→ number String @unique // gapless, e.g. VER-2026-0001
373→ companyId String
374→ company Company @relation(fields: [companyId], references: [id])
375→ type String // werkvertrag|dienstvertrag|wartung-sla|avv|nda|dpa
376→ title String
377→ status String @default("draft") // draft|sent|signed|active|expired|terminated
378→ valueCents Int @default(0)
379→ startDate DateTime?
380→ endDate DateTime? // null = unbefristet
381→ templateId String? // reference to a stored template
382→ dealId String? // optional link to originating deal
383→ projectId String? // optional link to project
384→ // E-signature hook (mock)
385→ signedAt DateTime?
386→ signedBy String? // signer name/email
387→ signedIp String?
388→ signToken String? // unique token for the signing link
389→ notes String?
390→ createdAt DateTime @default(now())
391→ updatedAt DateTime @updatedAt
392→}
393→
394→// ---------------------------------------------------------------------------
395→// Expenses / Ausgaben (adapted from PerfEx Expenses, Germanized for DATEV)
396→// ---------------------------------------------------------------------------
397→
398→model Expense {
399→ id String @id @default(cuid())
400→ number String @unique // gapless, e.g. AUS-2026-0001
401→ categoryId String // reise|software|hardware|fremdleistung|buero|marketing
402→ vendor String? // supplier / merchant
403→ description String
404→ amountCents Int // net amount
405→ taxBp Int @default(1900)
406→ grossCents Int @default(0)
407→ date DateTime @default(now())
408→ // linking
409→ companyId String? // customer this is billable to
410→ company Company? @relation(fields: [companyId], references: [id])
411→ projectId String? // project this relates to
412→ billable Boolean @default(false) // convert to customer invoice
413→ markupPct Int @default(0) // markup when re-billed
414→ // recurring
415→ recurring Boolean @default(false)
416→ recurringInterval String? // monthly|quarterly|yearly
417→ // receipt + export
418→ receiptHash String? // SHA-256 of stored receipt file (content-addressed)
419→ datevExported Boolean @default(false)
420→ // conversion
421→ convertedInvoiceId String? // link to the invoice created from this expense
422→ status String @default("recorded") // recorded|approved|invoiced|rejected
423→ createdAt DateTime @default(now())
424→ updatedAt DateTime @updatedAt
425→}
426→
427→// ---------------------------------------------------------------------------
428→// Support Tickets (PRD §6.7 + PerfEx Support Tickets + AI Integration)
429→// ---------------------------------------------------------------------------
430→
431→model Ticket {
432→ id String @id @default(cuid())
433→ number String @unique // gapless, e.g. TKT-2026-0001
434→ subject String
435→ status String @default("open") // open|pending|resolved|closed
436→ priority String @default("normal") // low|normal|high|urgent
437→ categoryId String // bug|anfrage|aenderung|konto|rechnung|hosting
438→ companyId String
439→ company Company @relation(fields: [companyId], references: [id])
440→ projectId String?
441→ licenseId String?
442→ // --- Ticket routing (agency model) ---
443→ // If the client belongs to an agency, the ticket is routed to that agency
444→ // (agencyCompanyId). The agency handles it; only if the agency escalates
445→ // does the ticket reach us (routedToAgency = false, escalatedToAdmin = true).
446→ agencyCompanyId String? // the reseller that owns this client (if any)
447→ routedToAgency Boolean @default(false) // ticket sent to agency inbox
448→ escalatedToAdmin Boolean @default(false) // agency escalated to us
449→ escalatedAt DateTime?
450→ // SLA
451→ slaResponseHours Int @default(8) // first response target
452→ slaResolveHours Int @default(48) // resolution target
453→ slaRespondedAt DateTime?
454→ slaResolvedAt DateTime?
455→ // AI
456→ aiSummary String? // LLM-generated summary of the conversation
457→ // assignee
458→ assignee String?
459→ createdAt DateTime @default(now())
460→ updatedAt DateTime @updatedAt
461→ messages TicketMessage[]
462→}
463→
464→model TicketMessage {
465→ id String @id @default(cuid())
466→ ticketId String
467→ ticket Ticket @relation(fields: [ticketId], references: [id])
468→ fromType String // customer|staff|system|agency
469→ fromName String
470→ body String
471→ createdAt DateTime @default(now())
472→}
473→
474→// ---------------------------------------------------------------------------
475→// Agency Applications (PRD §6.5 — reseller onboarding)
476→// ---------------------------------------------------------------------------
477→// When a company signs up, they may choose to become an agency (reseller).
478→// The application is stored here and awaits admin approval. On approval,
479→// the Company.isAgency flag is set, Company.agencyStatus = "approved", and
480→// an email is sent to the applicant with their discount percentage.
481→model AgencyApplication {
482→ id String @id @default(cuid())
483→ companyId String @unique
484→ company Company @relation(fields: [companyId], references: [id])
485→ status String @default("pending") // pending|approved|rejected
486→ // Discount the admin grants this agency (0-20%). Applied to all licenses
487→ // the agency buys from us. Admin-only decision.
488→ discountPct Int @default(0) // 0-20
489→ // Business justification fields (filled by the applicant)
490→ businessModel String? // e.g. "Webdesign agency", "IT consultant"
491→ expectedClientVolume String? // e.g. "10-20 clients"
492→ referredBy String? // how did they hear about us
493→ // Review
494→ reviewedBy String?
495→ reviewedAt DateTime?
496→ rejectReason String?
497→ appliedAt DateTime @default(now())
498→ createdAt DateTime @default(now())
499→ updatedAt DateTime @updatedAt
500→}
501→
502→// ---------------------------------------------------------------------------
503→// Estimates / Angebote (PRD §6.5 sales-docs — quotes that convert to invoice)
504→// ---------------------------------------------------------------------------
505→
506→model Estimate {
507→ id String @id @default(cuid())
508→ number String @unique // gapless, e.g. AN-2026-0001
509→ companyId String
510→ dealId String? // originating deal
511→ projectId String? // creates project when accepted
512→ subject String
513→ status String @default("draft") // draft|sent|accepted|rejected|expired
514→ validUntil DateTime?
515→ issueDate DateTime @default(now())
516→ acceptedAt DateTime?
517→ acceptedBy String?
518→ notes String?
519→ netCents Int @default(0)
520→ taxBp Int @default(1900)
521→ grossCents Int @default(0)
522→ // AI
523→ aiDraftFromBrief String? // flag: was this drafted from a brief via AI
524→ createdAt DateTime @default(now())
525→ updatedAt DateTime @updatedAt
526→ lines EstimateLine[]
527→}
528→
529→model EstimateLine {
530→ id String @id @default(cuid())
531→ estimateId String
532→ estimate Estimate @relation(fields: [estimateId], references: [id])
533→ description String
534→ quantity Int @default(1)
535→ unitCents Int
536→ totalCents Int
537→}
538→
539→// ---------------------------------------------------------------------------
540→// Accounting / Buchhaltung (adapted from Haben, German-law compliant)
541→// VAT return (Umsatzsteuer-Voranmeldung), EÜR, bank reconciliation, dunning.
542→// PRD §6.6: double-entry + ELSTER out of scope; this covers the agency-facing
543→// compliance layer (compute, validate, mock-submit) + bank matching.
544→// ---------------------------------------------------------------------------
545→
546→// Bank transactions imported from CAMT.053 or PSD2 (FinTS).
547→model BankTransaction {
548→ id String @id @default(cuid())
549→ amountCents Int // signed: + credit (incoming), - debit (outgoing)
550→ bookingDate DateTime
551→ valueDate DateTime
552→ partnerName String?
553→ partnerIban String?
554→ reference String?
555→ purpose String?
556→ matchedInvoiceId String?
557→ matchedStatus String @default("unmatched")
558→ matchReason String?
559→ importBatchId String?
560→ importedAt DateTime @default(now())
561→ createdAt DateTime @default(now())
562→}
563→
564→// VAT pre-registration periods (Umsatzsteuer-Voranmeldung)
565→model VatReturn {
566→ id String @id @default(cuid())
567→ periodYear Int
568→ periodMonth Int
569→ periodType String @default("monthly")
570→ status String @default("draft")
571→ k81StandardNetCents Int @default(0)
572→ k86ReducedNetCents Int @default(0)
573→ k66TaxFreeCents Int @default(0)
574→ k83TaxStandardCents Int @default(0)
575→ k65TaxReducedCents Int @default(0)
576→ k37InputTaxCents Int @default(0)
577→ outputTaxCents Int @default(0)
578→ inputTaxCents Int @default(0)
579→ payableCents Int @default(0)
580→ submittedAt DateTime?
581→ elsterRef String?
582→ acceptedAt DateTime?
583→ notes String?
584→ createdAt DateTime @default(now())
585→ updatedAt DateTime @updatedAt
586→}
587→
588→// Dunning levels for overdue invoices (Mahnwesen)
589→model DunningRun {
590→ id String @id @default(cuid())
591→ invoiceId String
592→ invoice Invoice @relation(fields: [invoiceId], references: [id])
593→ level Int
594→ status String @default("sent")
595→ feesCents Int @default(0)
596→ sentAt DateTime @default(now())
597→ createdAt DateTime @default(now())
598→}
599→
600→// ---------------------------------------------------------------------------
601→// Public API (PRD §5.5) — API tokens with scopes, webhooks with HMAC signing
602→// ---------------------------------------------------------------------------
603→
604→model ApiToken {
605→ id String @id @default(cuid())
606→ name String
607→ // The token shown to the user ONCE. We store only its SHA-256 hash so a
608→ // compromised DB does not leak usable tokens (like GitHub PATs).
609→ tokenHash String @unique
610→ tokenPrefix String // first 8 chars for identification (e.g. "aos_abc1…")
611→ scopes String // JSON array of scope strings, e.g. ["crm.company:read","finance.invoice:read"]
612→ lastUsedAt DateTime?
613→ expiresAt DateTime?
614→ revokedAt DateTime?
615→ createdAt DateTime @default(now())
616→}
617→
618→model Webhook {
619→ id String @id @default(cuid())
620→ url String // https endpoint to deliver to
621→ events String // JSON array, e.g. ["invoice.paid","contract.signed"]
622→ secret String // HMAC signing secret (stored, needed to verify signatures)
623→ active Boolean @default(true)
624→ // delivery stats
625→ sentCount Int @default(0)
626→ failCount Int @default(0)
627→ lastSentAt DateTime?
628→ lastStatus Int? // last HTTP status code received
629→ createdAt DateTime @default(now())
630→ updatedAt DateTime @updatedAt
631→}
632→
633→// ---------------------------------------------------------------------------
634→// Client Portal (PRD §6.3) — milestone approvals with evidence
635→// ---------------------------------------------------------------------------
636→
637→model PortalApproval {
638→ id String @id @default(cuid())
639→ projectId String
640→ project Project @relation(fields: [projectId], references: [id])
641→ title String // e.g. "Design-Entwürfe freigeben"
642→ description String?
643→ status String @default("pending") // pending|approved|rejected|changes-requested
644→ // evidence (PRD §6.3: "approvals with timestamp and IP evidence")
645→ decidedAt DateTime?
646→ decidedBy String? // client name
647→ decidedIp String? // real client IP at decision time
648→ decision String? // free-text reason/feedback
649→ // content hash for tamper-evidence
650→ contentHash String?
651→ createdAt DateTime @default(now())
652→ updatedAt DateTime @updatedAt
653→}
654→
655→// ---------------------------------------------------------------------------
656→// Knowledge Base (PRD §6.7) — internal + client-facing docs with versioning
657→// ---------------------------------------------------------------------------
658→
659→model Article {
660→ id String @id @default(cuid())
661→ slug String @unique
662→ title String
663→ category String // onboarding|launch-checklist|templates|handbuch|faq
664→ visibility String @default("internal") // internal|client|public
665→ excerpt String?
666→ content String // markdown
667→ tags String? // comma separated
668→ version Int @default(1)
669→ authorId String?
670→ authorName String?
671→ published Boolean @default(true)
672→ viewCount Int @default(0)
673→ createdAt DateTime @default(now())
674→ updatedAt DateTime @updatedAt
675→}
676→
677→// ---------------------------------------------------------------------------
678→// Haben-cloned features: Belege, Pauschalen, Anlagen/AfA, Kasse
679→// ---------------------------------------------------------------------------
680→
681→// Belege (receipts/documents) — content-addressed storage (PRD §5.5)
682→model Beleg {
683→ id String @id @default(cuid())
684→ number String @unique // gapless, e.g. BEL-2026-0001
685→ type String // rechnung-eingang|rechnung-ausgang|quittung|kassenbeleg|bankbeleg|sonstiges
686→ // content-addressed (SHA-256 hash of the file content)
687→ fileHash String @unique
688→ fileName String
689→ fileType String // application/pdf, image/jpeg, etc.
690→ fileSizeBytes Int
691→ // metadata extracted from the document
692→ vendor String? // Rechnungssteller
693→ invoiceNumber String? // Rechnungsnummer des Lieferanten
694→ amountCents Int? // Bruttobetrag auf dem Beleg
695→ amountNetCents Int? // Netto (falls extrahiert)
696→ taxBp Int? // USt %
697→ bookingDate DateTime?
698→ // linking
699→ expenseId String? // link to Expense if billable
700→ invoiceId String? // link to Invoice if outgoing
701→ // OCR / AI
702→ ocrText String? // extracted text (optional, via Jina/AI)
703→ // GoBD
704→ archivedAt DateTime?
705→ retentionUntil DateTime? // Aufbewahrung bis
706→ createdAt DateTime @default(now())
707→}
708→
709→// Pauschalen (flat-rate allowances) — Homeoffice, Kilometer, Verpflegung
710→model Pauschale {
711→ id String @id @default(cuid())
712→ type String // homeoffice|kilometer|verpflegung
713→ // homeoffice: €4.17/day (2026: €6.92/day up to €1.260/year)
714→ // kilometer: €0.30/km (car), €0.38/km (car w/ pass), or actual
715→ // verpflegung: €14 (8-14h), €24 (>14h, same day), €28 (overnight)
716→ date DateTime
717→ userId String? // employee
718→ amountCents Int // computed amount
719→ // details per type
720→ days Int? // homeoffice: 1; verpflegung: 1
721→ km Int? // kilometer: distance
722→ vehicleType String? // kilometer: auto|rad|fuss
723→ tripPurpose String? // kilometer: geschäftlich|fortbildung|umzug
724→ hoursAway Int? // verpflegung: hours away from office
725→ overnight Boolean @default(false) // verpflegung: overnight stay
726→ description String?
727→ projectId String? // link to project if billable
728→ expenseId String? // link to generated expense
729→ createdAt DateTime @default(now())
730→}
731→
732→// Anlagenverzeichnis & AfA (asset register + depreciation)
733→model Anlage {
734→ id String @id @default(cuid())
735→ number String @unique // e.g. ANL-2026-0001
736→ name String // "MacBook Pro 16"
737→ category String // hardware|software|mobiliar|fahrzeug|immobilie
738→ // acquisition
739→ purchaseDate DateTime
740→ purchaseCostCents Int // Anschaffungskosten (netto)
741→ taxBp Int @default(1900) // USt bei Anschaffung
742→ // AfA (depreciation)
743→ afaMethod String @default("linear") // linear|degressiv
744→ usefulLifeYears Int @default(3) // Nutzungsdauer (AfA-Tabelle)
745→ salvageValueCents Int @default(0) // Restwert
746→ // GWG (Geringwertiger Wirtschaftsgüter ≤ €800 net → Sofortabschreibung)
747→ isGWG Boolean @default(false) // GWG ≤ €800 → immediate expense
748→ // Sammelposten (€251-€1000 → Sammelabschreibung über 5 Jahre)
749→ isSammelposten Boolean @default(false)
750→ // computed
751→ annualAfaCents Int @default(0) // jährliche AfA
752→ accumulatedAfaCents Int @default(0) // kumulierte AfA
753→ bookValueCents Int @default(0) // Buchwert (purchase - accumulated AfA)
754→ // status
755→ status String @default("active") // active|sold|scrapped|fully-depreciated
756→ soldDate DateTime?
757→ soldPriceCents Int?
758→ createdAt DateTime @default(now())
759→ updatedAt DateTime @updatedAt
760→}
761→
762→// Kassenbuch (cash book for Barzahlungen — § 146 AO, § 22 UStG)
763→model KassenbuchEntry {
764→ id String @id @default(cuid())
765→ number String @unique // gapless, e.g. KAS-2026-0001
766→ date DateTime
767→ type String // einnahme|ausgabe
768→ description String
769→ amountCents Int // signed: + for einnahme, - for ausgabe
770→ taxBp Int? // USt % (if applicable)
771→ taxFree Boolean @default(false) // steuerfrei
772→ // receipt link
773→ belegId String? // link to Beleg (Kassenbeleg)
774→ // balance after this entry (laufender Kassenstand)
775→ balanceCents Int @default(0)
776→ // GoBD: Kassenbuch ist unveränderlich (elektronische Aufzeichnung)
777→ createdAt DateTime @default(now())
778→}
779→
780→
781→// ---------------------------------------------------------------------------
782→// SKR03/SKR04 Kontenrahmen + doppelte Buchführung (Haben clone)
783→// ---------------------------------------------------------------------------
784→
785→model Konto {
786→ id String @id @default(cuid())
787→ nummer String @unique
788→ name String
789→ rahmen String @default("skr04")
790→ art String // aktiv|passiv|ertrag|aufwand
791→ parentId String?
792→ locked Boolean @default(false)
793→ sollBuchungen Buchungssatz[] @relation("SollKonto")
794→ habenBuchungen Buchungssatz[] @relation("HabenKonto")
795→ createdAt DateTime @default(now())
796→}
797→
798→model Buchungssatz {
799→ id String @id @default(cuid())
800→ number String @unique
801→ belegdatum DateTime
802→ buchungsdatum DateTime @default(now())
803→ sollKontoId String
804→ sollKonto Konto @relation("SollKonto", fields: [sollKontoId], references: [id])
805→ habenKontoId String
806→ habenKonto Konto @relation("HabenKonto", fields: [habenKontoId], references: [id])
807→ betragCents Int
808→ buchungstext String
809→ belegNummer String?
810→ steuerBp Int?
811→ steuerKontoId String?
812→ festgeschrieben Boolean @default(false)
813→ festgeschriebenAt DateTime?
814→ festgeschriebenHash String?
815→ belegId String?
816→ invoiceId String?
817→ expenseId String?
818→ reverseCharge Boolean @default(false)
819→ par19UStG Boolean @default(false)
820→ createdAt DateTime @default(now())
821→}
822→
823→model EuerEntry {
824→ id String @id @default(cuid())
825→ jahr Int
826→ zeile String
827→ label String
828→ art String
829→ betragCents Int
830→ kontoNummern String?
831→ createdAt DateTime @default(now())
832→}
833→
834→model Jahreserklaerung {
835→ id String @id @default(cuid())
836→ jahr Int
837→ art String
838→ status String @default("draft")
839→ kennzahlen String?
840→ elsterRef String?
841→ submittedAt DateTime?
842→ acceptedAt DateTime?
843→ notes String?
844→ createdAt DateTime @default(now())
845→ updatedAt DateTime @updatedAt
846→}
847→
848→model Jahresarchiv {
849→ id String @id @default(cuid())
850→ jahr Int
851→ prevArchivId String?
852→ archivHash String @unique
853→ buchungenCount Int
854→ belegeCount Int
855→ rechnungenCount Int
856→ zipFileName String
857→ zipSizeBytes Int
858→ createdDate DateTime @default(now())
859→ createdBy String
860→ notes String?
861→}
862→
863→// ---------------------------------------------------------------------------
864→// Custom Fields (PRD §5.5: "Custom fields: JSONB with a schema table per entity")
865→// ---------------------------------------------------------------------------
866→
867→model CustomFieldDef {
868→ id String @id @default(cuid())
869→ entityType String // company|person|deal|project|invoice|ticket|contract
870→ key String // field key, e.g. "branche", "lead_source_detail"
871→ label String // display label, e.g. "Branche"
872→ type String // string|number|boolean|date|select|multiselect
873→ options String? // JSON array for select/multiselect
874→ required Boolean @default(false)
875→ sortOrder Int @default(0)
876→ values CustomFieldValue[]
877→ createdAt DateTime @default(now())
878→ updatedAt DateTime @updatedAt
879→
880→ @@unique([entityType, key])
881→}
882→
883→model CustomFieldValue {
884→ id String @id @default(cuid())
885→ fieldDefId String
886→ fieldDef CustomFieldDef @relation(fields: [fieldDefId], references: [id])
887→ entityType String // denormalized for fast lookup
888→ entityId String // the entity's ID
889→ value String? // JSON-encoded value (string, number, bool, array)
890→ createdAt DateTime @default(now())
891→ updatedAt DateTime @updatedAt
892→
893→ @@unique([entityType, entityId, fieldDefId])
894→}
895→
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,426 +0,0 @@
1→Initializing deployment
2→Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
3→Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
4→remote: Enumerating objects: 1836, done.
5→remote: Counting objects: 0% (1/1836) remote: Counting objects: 1% (19/1836) remote: Counting objects: 2% (37/1836) remote: Counting objects: 3% (56/1836) remote: Counting objects: 4% (74/1836) remote: Counting objects: 5% (92/1836) remote: Counting objects: 6% (111/1836) remote: Counting objects: 7% (129/1836) remote: Counting objects: 8% (147/1836) remote: Counting objects: 9% (166/1836) remote: Counting objects: 10% (184/1836) remote: Counting objects: 11% (202/1836) remote: Counting objects: 12% (221/1836) remote: Counting objects: 13% (239/1836) remote: Counting objects: 14% (258/1836) remote: Counting objects: 15% (276/1836) remote: Counting objects: 16% (294/1836) remote: Counting objects: 17% (313/1836) remote: Counting objects: 18% (331/1836) remote: Counting objects: 19% (349/1836) remote: Counting objects: 20% (368/1836) remote: Counting objects: 21% (386/1836) remote: Counting objects: 22% (404/1836) remote: Counting objects: 23% (423/1836) remote: Counting objects: 24% (441/1836) remote: Counting objects: 25% (459/1836) remote: Counting objects: 26% (478/1836) remote: Counting objects: 27% (496/1836) remote: Counting objects: 28% (515/1836) remote: Counting objects: 29% (533/1836) remote: Counting objects: 30% (551/1836) remote: Counting objects: 31% (570/1836) remote: Counting objects: 32% (588/1836) remote: Counting objects: 33% (606/1836) remote: Counting objects: 34% (625/1836) remote: Counting objects: 35% (643/1836) remote: Counting objects: 36% (661/1836) remote: Counting objects: 37% (680/1836) remote: Counting objects: 38% (698/1836) remote: Counting objects: 39% (717/1836) remote: Counting objects: 40% (735/1836) remote: Counting objects: 41% (753/1836) remote: Counting objects: 42% (772/1836) remote: Counting objects: 43% (790/1836) remote: Counting objects: 44% (808/1836) remote: Counting objects: 45% (827/1836) remote: Counting objects: 46% (845/1836) remote: Counting objects: 47% (863/1836) remote: Counting objects: 48% (882/1836) remote: Counting objects: 49% (900/1836) remote: Counting objects: 50% (918/1836) remote: Counting objects: 51% (937/1836) remote: Counting objects: 52% (955/1836) remote: Counting objects: 53% (974/1836) remote: Counting objects: 54% (992/1836) remote: Counting objects: 55% (1010/1836) remote: Counting objects: 56% (1029/1836) remote: Counting objects: 57% (1047/1836) remote: Counting objects: 58% (1065/1836) remote: Counting objects: 59% (1084/1836) remote: Counting objects: 60% (1102/1836) remote: Counting objects: 61% (1120/1836) remote: Counting objects: 62% (1139/1836) remote: Counting objects: 63% (1157/1836) remote: Counting objects: 64% (1176/1836) remote: Counting objects: 65% (1194/1836) remote: Counting objects: 66% (1212/1836) remote: Counting objects: 67% (1231/1836) remote: Counting objects: 68% (1249/1836) remote: Counting objects: 69% (1267/1836) remote: Counting objects: 70% (1286/1836) remote: Counting objects: 71% (1304/1836) remote: Counting objects: 72% (1322/1836) remote: Counting objects: 73% (1341/1836) remote: Counting objects: 74% (1359/1836) remote: Counting objects: 75% (1377/1836) remote: Counting objects: 76% (1396/1836) remote: Counting objects: 77% (1414/1836) remote: Counting objects: 78% (1433/1836) remote: Counting objects: 79% (1451/1836) remote: Counting objects: 80% (1469/1836) remote: Counting objects: 81% (1488/1836) remote: Counting objects: 82% (1506/1836) remote: Counting objects: 83% (1524/1836) remote: Counting objects: 84% (1543/1836) remote: Counting objects: 85% (1561/1836) remote: Counting objects: 86% (1579/1836) remote: Counting objects: 87% (1598/1836) remote: Counting objects: 88% (1616/1836) remote: Counting objects: 89% (1635/1836) remote: Counting objects: 90% (1653/1836) remote: Counting objects: 91% (1671/1836) remote: Counting objects: 92% (1690/1836) remote: Counting objects: 93% (1708/1836) remote: Counting objects: 94% (1726/1836) remote: Counting objects: 95% (1745/1836) remote: Counting objects: 96% (1763/1836) remote: Counting objects: 97% (1781/1836) remote: Counting objects: 98% (1800/1836) remLine truncated
6→remote: Compressing objects: 0% (1/1379) remote: Compressing objects: 1% (14/1379) remote: Compressing objects: 2% (28/1379) remote: Compressing objects: 3% (42/1379) remote: Compressing objects: 4% (56/1379) remote: Compressing objects: 5% (69/1379) remote: Compressing objects: 6% (83/1379) remote: Compressing objects: 7% (97/1379) remote: Compressing objects: 8% (111/1379) remote: Compressing objects: 9% (125/1379) remote: Compressing objects: 10% (138/1379) remote: Compressing objects: 11% (152/1379) remote: Compressing objects: 12% (166/1379) remote: Compressing objects: 13% (180/1379) remote: Compressing objects: 14% (194/1379) remote: Compressing objects: 15% (207/1379) remote: Compressing objects: 16% (221/1379) remote: Compressing objects: 17% (235/1379) remote: Compressing objects: 18% (249/1379) remote: Compressing objects: 19% (263/1379) remote: Compressing objects: 20% (276/1379) remote: Compressing objects: 21% (290/1379) remote: Compressing objects: 22% (304/1379) remote: Compressing objects: 23% (318/1379) remote: Compressing objects: 24% (331/1379) remote: Compressing objects: 25% (345/1379) remote: Compressing objects: 26% (359/1379) remote: Compressing objects: 27% (373/1379) remote: Compressing objects: 28% (387/1379) remote: Compressing objects: 29% (400/1379) remote: Compressing objects: 30% (414/1379) remote: Compressing objects: 31% (428/1379) remote: Compressing objects: 32% (442/1379) remote: Compressing objects: 33% (456/1379) remote: Compressing objects: 34% (469/1379) remote: Compressing objects: 35% (483/1379) remote: Compressing objects: 36% (497/1379) remote: Compressing objects: 37% (511/1379) remote: Compressing objects: 38% (525/1379) remote: Compressing objects: 39% (538/1379) remote: Compressing objects: 40% (552/1379) remote: Compressing objects: 41% (566/1379) remote: Compressing objects: 42% (580/1379) remote: Compressing objects: 43% (593/1379) remote: Compressing objects: 44% (607/1379) remote: Compressing objects: 45% (621/1379) remote: Compressing objects: 46% (635/1379) remote: Compressing objects: 47% (649/1379) remote: Compressing objects: 48% (662/1379) remote: Compressing objects: 49% (676/1379) remote: Compressing objects: 50% (690/1379) remote: Compressing objects: 51% (704/1379) remote: Compressing objects: 52% (718/1379) remote: Compressing objects: 53% (731/1379) remote: Compressing objects: 54% (745/1379) remote: Compressing objects: 55% (759/1379) remote: Compressing objects: 56% (773/1379) remote: Compressing objects: 57% (787/1379) remote: Compressing objects: 58% (800/1379) remote: Compressing objects: 59% (814/1379) remote: Compressing objects: 60% (828/1379) remote: Compressing objects: 61% (842/1379) remote: Compressing objects: 62% (855/1379) remote: Compressing objects: 63% (869/1379) remote: Compressing objects: 64% (883/1379) remote: Compressing objects: 65% (897/1379) remote: Compressing objects: 66% (911/1379) remote: Compressing objects: 67% (924/1379) remote: Compressing objects: 68% (938/1379) remote: Compressing objects: 69% (952/1379) remote: Compressing objects: 70% (966/1379) remote: Compressing objects: 71% (980/1379) remote: Compressing objects: 72% (993/1379) remote: Compressing objects: 73% (1007/1379) remote: Compressing objects: 74% (1021/1379) remote: Compressing objects: 75% (1035/1379) remote: Compressing objects: 76% (1049/1379) remote: Compressing objects: 77% (1062/1379) remote: Compressing objects: 78% (1076/1379) remote: Compressing objects: 79% (1090/1379) remote: Compressing objects: 80% (1104/1379) remote: Compressing objects: 81% (1117/1379) remote: Compressing objects: 82% (1131/1379) remote: Compressing objects: 83% (1145/1379) remote: Compressing objects: 84% (1159/1379) remote: Compressing objects: 85% (1173/1379) remote: Compressing objects: 86% (1186/1379) remote: Compressing objects: 87% (1200/1379) remote: Compressing objects: 88% (1214/1379) remote: Compressing objects: 89% (1228/1379) remote: Compressing objects: 90% (1242/1379) remote: Compressing objects: 91% (1255/1379) remote: Compressing objects: 92% (1269/1379) remote: Compressing objects: 93% (1283/1379) Line truncated
7→Receiving objects: 0% (1/1836) Receiving objects: 1% (19/1836) Receiving objects: 2% (37/1836) Receiving objects: 3% (56/1836) Receiving objects: 4% (74/1836) Receiving objects: 5% (92/1836) Receiving objects: 6% (111/1836) Receiving objects: 7% (129/1836) Receiving objects: 8% (147/1836) Receiving objects: 9% (166/1836) Receiving objects: 10% (184/1836) Receiving objects: 11% (202/1836) Receiving objects: 12% (221/1836) Receiving objects: 13% (239/1836) Receiving objects: 14% (258/1836) Receiving objects: 15% (276/1836) Receiving objects: 16% (294/1836) Receiving objects: 17% (313/1836) Receiving objects: 18% (331/1836) Receiving objects: 19% (349/1836) Receiving objects: 20% (368/1836) Receiving objects: 21% (386/1836) Receiving objects: 22% (404/1836) Receiving objects: 23% (423/1836) Receiving objects: 24% (441/1836) Receiving objects: 25% (459/1836) Receiving objects: 26% (478/1836) Receiving objects: 27% (496/1836) Receiving objects: 28% (515/1836) Receiving objects: 29% (533/1836) Receiving objects: 30% (551/1836) Receiving objects: 31% (570/1836) Receiving objects: 32% (588/1836) Receiving objects: 33% (606/1836) Receiving objects: 34% (625/1836) Receiving objects: 35% (643/1836) Receiving objects: 36% (661/1836) Receiving objects: 37% (680/1836) Receiving objects: 38% (698/1836) Receiving objects: 39% (717/1836) Receiving objects: 40% (735/1836) Receiving objects: 41% (753/1836) Receiving objects: 42% (772/1836) Receiving objects: 43% (790/1836) Receiving objects: 44% (808/1836) Receiving objects: 45% (827/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 46% (845/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 47% (863/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 48% (882/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 49% (900/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 50% (918/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 51% (937/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 52% (955/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 52% (973/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 53% (974/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 54% (992/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 55% (1010/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 56% (1029/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 57% (1047/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 58% (1065/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 59% (1084/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 60% (1102/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 61% (1120/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 62% (1139/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 63% (1157/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 64% (1176/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 65% (1194/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 66% (1212/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 67% (1231/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 68% (1249/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 69% (1267/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 70% (1286/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 71% (1304/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 72% (1322/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 73% (1341/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 74% (1359/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 75% (1377/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 76% (1396/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 77% (1414/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 78% (1433/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 79% (1451/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 80% (1469/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 81% (1488/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 82% (1506/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 83% (1524/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 84% (1543/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 85% (1561/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 86% (1579/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 87% (1598/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 88% (1616/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 89% (1635/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 90% (1653/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 91% (1671/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 92% (1690/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 93% (1708/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 94% (1726/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 95% (1745/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 96% (1763/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 97% (1781/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 98% (1800/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 99% (1818/1836), 47.46 MiB | 31.63 MiB/s remote: Total 183Line truncated
8→Receiving objects: 100% (1836/1836), 47.46 MiB | 31.63 MiB/s␍Receiving objects: 100% (1836/1836), 47.65 MiB | 31.60 MiB/s, done.
9→Resolving deltas: 0% (0/316)␍Resolving deltas: 1% (4/316)␍Resolving deltas: 2% (7/316)␍Resolving deltas: 3% (10/316)␍Resolving deltas: 4% (13/316)␍Resolving deltas: 5% (16/316)␍Resolving deltas: 6% (19/316)␍Resolving deltas: 7% (23/316)␍Resolving deltas: 8% (26/316)␍Resolving deltas: 9% (29/316)␍Resolving deltas: 10% (32/316)␍Resolving deltas: 11% (35/316)␍Resolving deltas: 12% (38/316)␍Resolving deltas: 13% (42/316)␍Resolving deltas: 14% (45/316)␍Resolving deltas: 15% (48/316)␍Resolving deltas: 16% (51/316)␍Resolving deltas: 17% (54/316)␍Resolving deltas: 18% (57/316)␍Resolving deltas: 19% (61/316)␍Resolving deltas: 20% (64/316)␍Resolving deltas: 21% (67/316)␍Resolving deltas: 22% (70/316)␍Resolving deltas: 23% (73/316)␍Resolving deltas: 24% (76/316)␍Resolving deltas: 25% (79/316)␍Resolving deltas: 26% (83/316)␍Resolving deltas: 27% (86/316)␍Resolving deltas: 28% (89/316)␍Resolving deltas: 29% (92/316)␍Resolving deltas: 30% (95/316)␍Resolving deltas: 31% (98/316)␍Resolving deltas: 32% (102/316)␍Resolving deltas: 33% (105/316)␍Resolving deltas: 34% (108/316)␍Resolving deltas: 35% (111/316)␍Resolving deltas: 36% (114/316)␍Resolving deltas: 37% (117/316)␍Resolving deltas: 38% (121/316)␍Resolving deltas: 39% (124/316)␍Resolving deltas: 40% (127/316)␍Resolving deltas: 41% (130/316)␍Resolving deltas: 42% (133/316)␍Resolving deltas: 43% (136/316)␍Resolving deltas: 44% (140/316)␍Resolving deltas: 45% (143/316)␍Resolving deltas: 46% (146/316)␍Resolving deltas: 47% (149/316)␍Resolving deltas: 48% (152/316)␍Resolving deltas: 49% (155/316)␍Resolving deltas: 50% (159/316)␍Resolving deltas: 51% (162/316)␍Resolving deltas: 52% (165/316)␍Resolving deltas: 53% (168/316)␍Resolving deltas: 54% (171/316)␍Resolving deltas: 55% (174/316)␍Resolving deltas: 56% (177/316)␍Resolving deltas: 57% (182/316)␍Resolving deltas: 58% (184/316)␍Resolving deltas: 59% (188/316)␍Resolving deltas: 60% (190/316)␍Resolving deltas: 61% (193/316)␍Resolving deltas: 62% (196/316)␍Resolving deltas: 63% (200/316)␍Resolving deltas: 64% (203/316)␍Resolving deltas: 65% (206/316)␍Resolving deltas: 66% (209/316)␍Resolving deltas: 67% (213/316)␍Resolving deltas: 68% (215/316)␍Resolving deltas: 69% (219/316)␍Resolving deltas: 70% (222/316)␍Resolving deltas: 71% (225/316)␍Resolving deltas: 72% (229/316)␍Resolving deltas: 73% (231/316)␍Resolving deltas: 74% (234/316)␍Resolving deltas: 75% (237/316)␍Resolving deltas: 76% (241/316)␍Resolving deltas: 77% (244/316)␍Resolving deltas: 78% (247/316)␍Resolving deltas: 79% (250/316)␍Resolving deltas: 80% (253/316)␍Resolving deltas: 81% (256/316)␍Resolving deltas: 82% (260/316)␍Resolving deltas: 83% (263/316)␍Resolving deltas: 84% (267/316)␍Resolving deltas: 85% (269/316)␍Resolving deltas: 86% (272/316)␍Resolving deltas: 87% (276/316)␍Resolving deltas: 88% (279/316)␍Resolving deltas: 89% (282/316)␍Resolving deltas: 90% (285/316)␍Resolving deltas: 91% (288/316)␍Resolving deltas: 92% (291/316)␍Resolving deltas: 93% (294/316)␍Resolving deltas: 94% (298/316)␍Resolving deltas: 95% (301/316)␍Resolving deltas: 96% (304/316)␍Resolving deltas: 97% (307/316)␍Resolving deltas: 98% (310/316)␍Resolving deltas: 99% (313/316)␍Resolving deltas: 100% (316/316)␍Resolving deltas: 100% (316/316), done.
10→> Installing railpack, please wait…
11→____ _ _ _
12→| _ \ __ _(_) |_ __ __ _ ___| | __
13→| |_) / _` | | | '_ \ / _` |/ __| |/ /
14→| _ < (_| | | | |_) | (_| | (__| <
15→|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
16→|_|
17→Railpack is now installed!
18→Run 'railpack --help' to get started
19→railpack-dfm-aos-lgbcnc-INtHrR
20→Preparing Railpack build plan...
21→╭─────────────────╮
22→│ Railpack 0.15.4 │
23→╰─────────────────╯
24→↳ Detected Node
25→↳ Using bun package manager
26→Packages
27→──────────
28→bun │ 1.4.4 │ railpack default (latest)
29→node │ 26.12.1 │ railpack default (latest)
30→Steps
31→──────────
32→▸ install
33→$ bun install --frozen-lockfile
34→▸ build
35→$ bun run build
36→Deploy
37→──────────
38→$ bun run start
39→✅ Railpack prepare completed.
40→Building with Railpack frontend...
41→#0 building with "railpack-dfm-aos-lgbcnc-INtHrR" instance using docker-container driver
42→#1 [internal] booting buildkit
43→#1 pulling image moby/buildkit:buildx-stable-1
44→#1 pulling image moby/buildkit:buildx-stable-1 1.1s done
45→#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-inthrr0
46→#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-inthrr0 0.6s done
47→#1 DONE 1.7s
48→#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
49→#2 DONE 1.4s
50→#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
51→#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 0.0s done
52→#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
53→#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 2.10MB / 7.90MB 0.3s
54→#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
55→#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.4s done
56→#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.5s done
57→#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
58→#3 DONE 0.7s
59→#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
60→#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.1s done
61→#3 DONE 0.8s
62→#4 load build definition from railpack-plan.json
63→#4 transferring dockerfile: 5.11kB done
64→#4 DONE 0.0s
65→#5 [railpack] secrets hash
66→#5 DONE 0.0s
67→#6 loading .
68→#6 DONE 0.0s
69→#7 [railpack] loading secrets
70→#7 resolve docker.io/library/alpine:latest
71→#7 ...
72→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
73→#8 resolve ghcr.io/railwayapp/railpack-builder:latest 0.9s done
74→#8 DONE 1.0s
75→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
76→#8 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 0B / 119B 0.2s
77→#8 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0B / 868.40kB 0.2s
78→#8 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.3s done
79→#8 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.3s done
80→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 0B / 237.08MB 0.2s
81→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 0B / 53.72MB 0.2s
82→#8 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 0B / 32B 0.2s
83→#8 ...
84→#5 [railpack] secrets hash
85→#5 DONE 0.0s
86→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
87→#8 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.2s done
88→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 0B / 67.81MB 0.2s
89→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 7.34MB / 53.72MB 0.5s
90→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 0B / 25.64MB 0.2s
91→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 17.83MB / 237.08MB 0.6s
92→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 7.34MB / 67.81MB 0.5s
93→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 14.68MB / 53.72MB 0.8s
94→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 6.29MB / 25.64MB 0.5s
95→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 30.41MB / 237.08MB 0.9s
96→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 14.68MB / 67.81MB 0.8s
97→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 10.49MB / 25.64MB 0.6s
98→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 18.87MB / 53.72MB 1.1s
99→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 14.68MB / 25.64MB 0.8s
100→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 17.83MB / 25.64MB 0.9s
101→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 48.23MB / 237.08MB 1.4s
102→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 23.07MB / 53.72MB 1.4s
103→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 22.02MB / 67.81MB 1.1s
104→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 23.07MB / 25.64MB 1.1s
105→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 26.21MB / 53.72MB 1.5s
106→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 29.36MB / 67.81MB 1.4s
107→#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 1.3s done
108→#8 ...
109→#7 [railpack] loading secrets
110→#7 resolve docker.io/library/alpine:latest 1.5s done
111→#7 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.9s done
112→#7 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 0.5s done
113→#7 DONE 2.9s
114→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
115→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 30.15MB / 53.72MB 1.7s
116→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 69.21MB / 237.08MB 1.8s
117→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 35.65MB / 67.81MB 1.5s
118→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 0B / 49.39MB 0.2s
119→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 35.65MB / 53.72MB 2.0s
120→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 40.89MB / 67.81MB 1.7s
121→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 6.29MB / 49.39MB 0.5s
122→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 83.89MB / 237.08MB 2.1s
123→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 40.89MB / 53.72MB 2.3s
124→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 48.23MB / 67.81MB 2.0s
125→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 10.49MB / 49.39MB 0.6s
126→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 97.52MB / 237.08MB 2.4s
127→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 52.43MB / 67.81MB 2.1s
128→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 14.68MB / 49.39MB 0.8s
129→#8 ...
130→#9 [railpack] copy secrets hash
131→#9 DONE 0.7s
132→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
133→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 18.87MB / 49.39MB 0.9s
134→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 46.14MB / 53.72MB 2.6s
135→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 23.07MB / 49.39MB 1.1s
136→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 111.15MB / 237.08MB 2.7s
137→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 59.77MB / 67.81MB 2.4s
138→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 51.38MB / 53.72MB 2.9s
139→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 63.96MB / 67.81MB 2.6s
140→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 30.41MB / 49.39MB 1.4s
141→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 126.88MB / 237.08MB 3.0s
142→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 36.70MB / 49.39MB 1.5s
143→#8 ...
144→#10 [railpack] hash used secrets
145→#10 DONE 0.7s
146→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
147→#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 3.2s done
148→#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 2.9s done
149→#8 ...
150→#11 [railpack] copy used secrets hash
151→#11 DONE 0.0s
152→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
153→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 145.75MB / 237.08MB 3.3s
154→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 40.89MB / 49.39MB 1.7s
155→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 46.14MB / 49.39MB 1.8s
156→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 168.15MB / 237.08MB 3.6s
157→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.0s
158→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 181.40MB / 237.08MB 3.8s
159→#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.2s done
160→#8 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
161→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 205.52MB / 237.08MB 4.1s
162→#8 ...
163→#6 loading .
164→#6 transferring context: 127.67MB 3.8s done
165→#6 DONE 4.0s
166→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
167→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 231.05MB / 237.08MB 4.4s
168→#8 ...
169→#12 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
170→#12 resolve ghcr.io/railwayapp/railpack-runtime:latest 0.9s done
171→#12 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.3s done
172→#12 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 0.7s done
173→#12 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 3.4s done
174→#12 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.6s done
175→#12 DONE 5.6s
176→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
177→#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 4.7s done
178→#8 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 2.7s done
179→#8 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
180→#8 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.7s done
181→#8 DONE 9.4s
182→#13 install apt packages: libatomic1
183→#13 0.232 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
184→#13 0.314 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
185→#13 0.345 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
186→#13 0.374 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
187→#13 0.549 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
188→#13 0.575 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
189→#13 2.260 Fetched 10.2 MB in 2s (4830 kB/s)
190→#13 2.260 Reading package lists...
191→#13 4.151 Reading package lists...
192→#13 5.983 Building dependency tree...
193→#13 6.439 Reading state information...
194→#13 6.939 The following NEW packages will be installed:
195→#13 6.941 libatomic1
196→#13 7.101 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
197→#13 7.101 Need to get 9308 B of archives.
198→#13 7.101 After this operation, 46.1 kB of additional disk space will be used.
199→#13 7.101 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
200→#13 7.542 debconf: unable to initialize frontend: Dialog
201→#13 7.543 debconf: (TERM is not set, so the dialog frontend is not usable.)
202→#13 7.543 debconf: falling back to frontend: Readline
203→#13 7.543 debconf: unable to initialize frontend: Readline
204→#13 7.543 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
205→#13 7.543 debconf: falling back to frontend: Teletype
206→#13 7.550 debconf: unable to initialize frontend: Teletype
207→#13 7.550 debconf: (This frontend requires a controlling tty.)
208→#13 7.550 debconf: falling back to frontend: Noninteractive
209→#13 ...
210→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
211→#8 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 4.6s done
212→#8 DONE 14.0s
213→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
214→#8 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
215→#8 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
216→#8 ...
217→#13 install apt packages: libatomic1
218→#13 8.681 Fetched 9308 B in 0s (65.4 kB/s)
219→#13 8.727 Selecting previously unselected package libatomic1:amd64.
220→#13 8.727 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
221→#13 8.735 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
222→#13 8.756 Unpacking libatomic1:amd64 (14.2.0-19) ...
223→#13 8.817 Setting up libatomic1:amd64 (14.2.0-19) ...
224→#13 8.823 Processing triggers for libc-bin (2.41-12+deb13u4) ...
225→#13 DONE 9.4s
226→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
227→#8 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.1s done
228→#8 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
229→#8 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 7.1s done
230→#8 DONE 22.2s
231→#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
232→#8 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
233→#8 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
234→#8 DONE 22.2s
235→#14 mkdir /etc/mise
236→#14 DONE 1.5s
237→#15 create mise config
238→#15 DONE 0.0s
239→#16 install mise packages: bun, node
240→#16 0.142 mise by @jdx – installing 2 tools
241→#16 3.151 mise ███████████░░░░░ 0/2 · 3.0s
242→#16 3.151 bun@1.4.4 downloading 2.7s 51.8/51.8 MB · 22.0 MB/s
243→#16 3.151 node@26.12.1 downloading 2.7s 62.1/62.9 MB · 24.6 MB/s
244→#16 3.856 mise bun@1.4.4 1.4.4
245→#16 3.869 mise ✓ bun@1.4.4 3.4s bun-linux-x64.zip
246→#16 4.708 mise node@26.12.1 v26.12.1
247→#16 4.828 mise node@26.12.1 11.20.0
248→#16 4.861 mise ✓ node@26.12.1 4.4s node-v26.12.1-linux-x64.tar.gz
249→#16 4.861 mise ████████████████ 2/2 · installed 2 tools in 4.7s
250→#16 DONE 5.7s
251→#17 mkdir -p /app/node_modules/.cache
252→#17 DONE 0.2s
253→#18 copy bun.lock
254→#18 DONE 0.0s
255→#19 copy package.json
256→#19 DONE 0.1s
257→#20 copy /mise/shims
258→#20 DONE 0.0s
259→#21 copy skills/podcast-generate/package.json
260→#21 DONE 0.0s
261→#22 copy skills/skill-finder-cn/package.json
262→#22 DONE 0.0s
263→#23 copy skills/stock-analysis-skill/package.json
264→#23 DONE 0.0s
265→#24 copy skills/storyboard-manager/package.json
266→#24 DONE 0.0s
267→#25 copy prisma
268→#25 DONE 0.0s
269→#26 bun install --frozen-lockfile
270→#26 0.115 bun install v1.4.4 (38afee6c8)
271→#26 ...
272→#27 copy /mise/installs
273→#27 ...
274→#26 bun install --frozen-lockfile
275→#26 14.31
276→#26 14.31 + @tailwindcss/postcss@4.1.18
277→#26 14.31 + @types/react@19.2.8
278→#26 14.31 + @types/react-dom@19.2.3
279→#26 14.31 + bun-types@1.3.6
280→#26 14.31 + eslint@9.39.2
281→#26 14.31 + eslint-config-next@16.1.3
282→#26 14.31 + tailwindcss@4.1.18
283→#26 14.31 + tw-animate-css@1.4.0
284→#26 14.31 + typescript@5.9.3
285→#26 14.31 + @dnd-kit/core@6.3.1
286→#26 14.31 + @dnd-kit/sortable@10.0.0
287→#26 14.31 + @dnd-kit/utilities@3.2.2
288→#26 14.31 + @hookform/resolvers@5.2.2
289→#26 14.31 + @hugeicons/core-free-icons@4.3.5
290→#26 14.31 + @hugeicons/react@1.1.10
291→#26 14.31 + @mdxeditor/editor@3.52.3
292→#26 14.31 + @prisma/client@6.19.2
293→#26 14.31 + @radix-ui/react-accordion@1.2.12
294→#26 14.31 + @radix-ui/react-alert-dialog@1.1.15
295→#26 14.31 + @radix-ui/react-aspect-ratio@1.1.8
296→#26 14.31 + @radix-ui/react-avatar@1.1.11
297→#26 14.31 + @radix-ui/react-checkbox@1.3.3
298→#26 14.31 + @radix-ui/react-collapsible@1.1.12
299→#26 14.31 + @radix-ui/react-context-menu@2.2.16
300→#26 14.31 + @radix-ui/react-dialog@1.1.15
301→#26 14.31 + @radix-ui/react-dropdown-menu@2.1.16
302→#26 14.31 + @radix-ui/react-hover-card@1.1.15
303→#26 14.31 + @radix-ui/react-label@2.1.8
304→#26 14.31 + @radix-ui/react-menubar@1.1.16
305→#26 14.31 + @radix-ui/react-navigation-menu@1.2.14
306→#26 14.31 + @radix-ui/react-popover@1.1.15
307→#26 14.31 + @radix-ui/react-progress@1.1.8
308→#26 14.31 + @radix-ui/react-radio-group@1.3.8
309→#26 14.31 + @radix-ui/react-scroll-area@1.2.10
310→#26 14.31 + @radix-ui/react-select@2.2.6
311→#26 14.31 + @radix-ui/react-separator@1.1.8
312→#26 14.31 + @radix-ui/react-slider@1.3.6
313→#26 14.31 + @radix-ui/react-slot@1.2.4
314→#26 14.31 + @radix-ui/react-switch@1.2.6
315→#26 14.31 + @radix-ui/react-tabs@1.1.13
316→#26 14.31 + @radix-ui/react-toast@1.2.15
317→#26 14.31 + @radix-ui/react-toggle@1.1.10
318→#26 14.31 + @radix-ui/react-toggle-group@1.1.11
319→#26 14.31 + @radix-ui/react-tooltip@1.2.8
320→#26 14.31 + @reactuses/core@6.1.9
321→#26 14.31 + @tanstack/react-query@5.90.19
322→#26 14.31 + @tanstack/react-table@8.21.3
323→#26 14.31 + class-variance-authority@0.7.1
324→#26 14.31 + clsx@2.1.1
325→#26 14.31 + cmdk@1.1.1
326→#26 14.31 + date-fns@4.1.0
327→#26 14.31 + embla-carousel-react@8.6.0
328→#26 14.31 + framer-motion@14.7.1
329→#26 14.31 + imapflow@2.9.1
330→#26 14.31 + input-otp@1.4.2
331→#26 14.31 + lucide-react@1.62.0
332→#26 14.31 + motion@12.43.0
333→#26 14.31 + next@16.1.3
334→#26 14.31 + next-auth@4.24.13
335→#26 14.31 + next-intl@4.7.0
336→#26 14.31 + next-themes@0.4.6
337→#26 14.31 + prisma@6.19.2
338→#26 14.31 + react@19.2.3
339→#26 14.31 + react-day-picker@9.13.0
340→#26 14.31 + react-dom@19.2.3
341→#26 14.31 + react-hook-form@7.71.1
342→#26 14.31 + react-markdown@10.1.0
343→#26 14.31 + react-resizable-panels@3.0.6
344→#26 14.31 + react-syntax-highlighter@15.6.6
345→#26 14.31 + recharts@2.15.4
346→#26 14.31 + sharp@0.34.5
347→#26 14.31 + sonner@2.0.7
348→#26 14.31 + tailwind-merge@3.7.0
349→#26 14.31 + tailwindcss-animate@1.0.7
350→#26 14.31 + uuid@11.1.0
351→#26 14.31 + vaul@1.1.2
352→#26 14.31 + z-ai-web-dev-sdk@0.0.18
353→#26 14.31 + zod@4.3.5
354→#26 14.31 + zustand@5.0.10
355→#26 14.31
356→#26 14.31 858 packages installed [14.19s]
357→#26 DONE 16.1s
358→#28 copy / /app
359→#28 ...
360→#27 copy /mise/installs
361→#27 DONE 7.3s
362→#29 copy /usr/local/bin/mise
363→#29 DONE 1.2s
364→#28 copy / /app
365→#28 ...
366→#30 copy /etc/mise/config.toml
367→#30 DONE 0.1s
368→#31 copy /root/.local/state/mise
369→#31 DONE 0.0s
370→#28 copy / /app
371→#28 DONE 2.7s
372→#32 bun run build
373→#32 0.169 $ next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
374→#32 0.359 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
375→#32 1.293 ▲ Next.js 16.1.3 (Turbopack)
376→#32 1.294 - Environments: .env
377→#32 1.294
378→#32 1.340 Creating an optimized production build ...
379→#32 13.17 (node:98) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
380→#32 13.17 (Use `node --trace-deprecation ...` to show where the warning was created)
381→#32 31.57
382→#32 31.57 > Build error occurred
383→#32 31.57 Error: Turbopack build failed with 1 errors:
384→#32 31.57 ./node_modules/@prisma/client/index-browser.js:1:16
385→#32 31.57 Module not found: Can't resolve '.prisma/client/index-browser'
386→#32 31.57 > 1 | const prisma = require('.prisma/client/index-browser')
387→#32 31.57  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
388→#32 31.57  2 |
389→#32 31.57  3 | module.exports = prisma
390→#32 31.57  4 |
391→#32 31.57
392→#32 31.57
393→#32 31.57
394→#32 31.57 Import trace:
395→#32 31.57 Client Component Browser:
396→#32 31.57 ./node_modules/@prisma/client/index-browser.js [Client Component Browser]
397→#32 31.57 ./src/lib/db.ts [Client Component Browser]
398→#32 31.57 ./src/components/aos/portal-shell.tsx [Client Component Browser]
399→#32 31.57 ./src/components/aos/app-shell.tsx [Client Component Browser]
400→#32 31.57 ./src/components/aos/app-shell.tsx [Server Component]
401→#32 31.57 ./src/app/page.tsx [Server Component]
402→#32 31.57
403→#32 31.57 https://nextjs.org/docs/messages/module-not-found
404→#32 31.57
405→#32 31.57
406→#32 31.57 at ./node_modules/ (prisma/client/index-browser.js:1:16)
407→#32 31.57 at <unknown> (https://nextjs.org/docs/messages/module-not-found)
408→#32 31.72 error: script "build" exited with code 1
409→#32 ERROR: process "bun run build" did not complete successfully: exit code: 1
410→------
411→> bun run build:
412→31.57 ./src/components/aos/app-shell.tsx [Client Component Browser]
413→31.57 ./src/components/aos/app-shell.tsx [Server Component]
414→31.57 ./src/app/page.tsx [Server Component]
415→31.57
416→31.57 https://nextjs.org/docs/messages/module-not-found
417→31.57
418→31.57
419→31.57 at ./node_modules/ (prisma/client/index-browser.js:1:16)
420→31.57 at <unknown> (https://nextjs.org/docs/messages/module-not-found)
421→31.72 error: script "build" exited with code 1
422→------
423→ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
424→❌ Railpack build failed
425→railpack-dfm-aos-lgbcnc-INtHrR removed
426→Error occurred ❌, check the logs for details.
File diff suppressed because it is too large. Load diff
@@ -1,517 +0,0 @@
1→<p align="center">
2→ <a href="https://graphify.com"><img src="https://raw.githubusercontent.com/Graphify-Labs/graphify/v8/docs/graphify-logo.png" width="360" height="189" alt="Graphify"/></a>
3→</p>
4→
5→<p align="center">
6→ <a href="https://trendshift.io/repositories/25296?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-25296" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/25296" alt="Graphify-Labs%2Fgraphify | Trendshift" width="250" height="55"/></a>
7→</p>
8→
9→<div align="center">
10→<details><summary><b>Read this in other languages</b></summary>
11→
12→<a href="README.md">English</a> | <a href="docs/translations/README.zh-CN.md">简体中文</a> | <a href="docs/translations/README.ja-JP.md">日本語</a> | <a href="docs/translations/README.ko-KR.md">한국어</a> | <a href="docs/translations/README.de-DE.md">Deutsch</a> | <a href="docs/translations/README.fr-FR.md">Français</a> | <a href="docs/translations/README.es-ES.md">Español</a> | <a href="docs/translations/README.hi-IN.md">हिन्दी</a> | <a href="docs/translations/README.pt-BR.md">Português</a> | <a href="docs/translations/README.ru-RU.md">Русский</a> | <a href="docs/translations/README.ar-SA.md">العربية</a> | <a href="docs/translations/README.fa-IR.md">فارسی</a> | <a href="docs/translations/README.it-IT.md">Italiano</a> | <a href="docs/translations/README.pl-PL.md">Polski</a> | <a href="docs/translations/README.nl-NL.md">Nederlands</a> | <a href="docs/translations/README.tr-TR.md">Türkçe</a> | <a href="docs/translations/README.uk-UA.md">Українська</a> | <a href="docs/translations/README.vi-VN.md">Tiếng Việt</a> | <a href="docs/translations/README.id-ID.md">Bahasa Indonesia</a> | <a href="docs/translations/README.sv-SE.md">Svenska</a> | <a href="docs/translations/README.el-GR.md">Ελληνικά</a> | <a href="docs/translations/README.ro-RO.md">Română</a> | <a href="docs/translations/README.cs-CZ.md">Čeština</a> | <a href="docs/translations/README.fi-FI.md">Suomi</a> | <a href="docs/translations/README.da-DK.md">Dansk</a> | <a href="docs/translations/README.no-NO.md">Norsk</a> | <a href="docs/translations/README.hu-HU.md">Magyar</a> | <a href="docs/translations/README.th-TH.md">ภาษาไทย</a> | <a href="docs/translations/README.uz-UZ.md">Oʻzbekcha</a> | <a href="docs/translations/README.zh-TW.md">繁體中文</a> | <a href="docs/translations/README.fil-PH.md">Filipino</a> | <a href="docs/translations/README.he-IL.md">עברית</a>
13→
14→</details>
15→</div>
16→
17→<p align="center">
18→ <a href="https://pypi.org/project/graphifyy/"><img src="https://img.shields.io/pypi/v/graphifyy" alt="PyPI"/></a>
19→ <a href="https://github.com/Graphify-Labs/graphify/actions/workflows/ci.yml"><img src="https://github.com/Graphify-Labs/graphify/actions/workflows/ci.yml/badge.svg?branch=v8" alt="CI"/></a>
20→ <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue" alt="License: Apache-2.0"/></a>
21→ <a href="https://pepy.tech/project/graphifyy"><img src="https://img.shields.io/pepy/dt/graphifyy?color=blue&label=downloads" alt="Downloads"/></a>
22→ <a href="https://docs.graphify.com"><img src="https://img.shields.io/badge/Docs-docs.graphify.com-0b7285?style=flat&logo=readthedocs&logoColor=white" alt="Docs"/></a>
23→ <a href="https://app.graphify.com/login"><img src="https://img.shields.io/badge/Graphify%20Cloud-app.graphify.com-118d4f?style=flat&logoColor=white" alt="Graphify Cloud"/></a>
24→ <a href="https://discord.gg/graphify"><img src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat&logo=discord&logoColor=white" alt="Discord"/></a>
25→ <a href="https://www.youtube.com/@graphifylabs"><img src="https://img.shields.io/badge/YouTube-Graphify%20Labs-FF0000?style=flat&logo=youtube&logoColor=white" alt="YouTube"/></a>
26→ <a href="https://www.linkedin.com/company/graphify-labs"><img src="https://img.shields.io/badge/LinkedIn-Graphify%20Labs-0077B5?logo=linkedin" alt="LinkedIn"/></a>
27→ <a href="https://www.ycombinator.com/companies/graphify-labs"><img src="https://img.shields.io/badge/Y%20Combinator-S26-F0652F?style=flat&logo=ycombinator&logoColor=white" alt="YC S26"/></a>
28→</p>
29→
30→<p align="center">
31→ <b>Cut agent token spend by 80%.</b> Graphify Cloud is always-on memory that governs your agents, keeps code quality high, and proves correctness with formal verification. <a href="https://app.graphify.com/login"><b>Start a free 14-day trial &rarr;</b></a>
32→</p>
33→
34→Type `/graphify` in your AI coding assistant and it maps your entire project (code, docs, PDFs, images, videos) into a **knowledge graph** you can **query instead of grepping** through files.
35→
36→- **Code maps for free, fully local.** Code is parsed with tree-sitter AST: deterministic, no LLM, nothing leaves your machine. (Docs, PDFs, images and video use your assistant's model, or a configured API key, for a semantic pass.)
37→- **Every edge is explained.** Each connection is tagged `EXTRACTED` (explicit in the source) or `INFERRED` (resolved by graphify), so you can tell what was read directly from what was inferred.
38→- **Not a vector index.** No embeddings, no vector store: a real graph you traverse. Ask a question, trace the path between two things, or explain one concept.
39→
40→> [!NOTE]
41→> **Want this always-on?** [Graphify Cloud](https://app.graphify.com/login) keeps the graph live across your entire SDLC: monorepo and cross-repo support, formal verification, and code review with a bird's-eye view of your SDLC, plus connectors for Sentry, Jira, and more so incidents and tickets sit in the same graph as your code. **[Start a free 14-day trial at app.graphify.com](https://app.graphify.com/login)**.
42→
43→<p align="center">
44→ <img src="https://raw.githubusercontent.com/Graphify-Labs/graphify/v8/docs/graph-hero.png" alt="graphify's interactive graph.html showing the FastAPI codebase as a force-directed knowledge graph with a legend of detected communities" width="900">
45→</p>
46→<p align="center">
47→ <em>The FastAPI codebase mapped by graphify. Every node is a concept, colors are detected communities, and the whole thing is clickable in graph.html.</em>
48→</p>
49→
50→**Get started** (30 seconds). Needs Python 3.10+ and uv (or pipx):
51→
52→```bash
53→uv tool install graphifyy # install the CLI (or: pipx install graphifyy)
54→graphify install # detects your assistant and registers the skill
55→```
56→
57→Then, in your AI assistant:
58→
59→```
60→/graphify .
61→```
62→
63→That's it. You get **three files**:
64→
65→```
66→graphify-out/
67→├── graph.html open in any browser: click nodes, filter, search
68→├── GRAPH_REPORT.md the highlights: key concepts, surprising connections, suggested questions
69→└── graph.json the full graph: query it anytime without re-reading your files
70→```
71→
72→The persisted graph includes `graph.schema_version` so integrations can detect
73→incompatible format changes, plus `graph.graphify_version` identifying the
74→Graphify release that produced it.
75→
76→**One install, any assistant, any OS.** Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, and 20+ more, on macOS, Linux, and Windows: [pick your platform](#install).
77→
78→---
79→
80→## See it in action
81→
82→<p align="center">
83→ <img src="https://raw.githubusercontent.com/Graphify-Labs/graphify/v8/docs/demo-path.svg" alt="graphify path query: a terminal asks for the shortest path between FastAPI and ModelField, and the answer lights up hop by hop across the knowledge graph" width="900">
84→</p>
85→
86→Once the graph is built you query it instead of reading files. Real output, graphify run on the FastAPI codebase shown above:
87→
88→```text
89→$ graphify explain "APIRouter"
90→Node: APIRouter
91→ Source: routing.py L2210
92→ Community: 2
93→ Degree: 47
94→
95→Connections (47):
96→ --> RequestValidationError [uses] [INFERRED]
97→ --> Dependant [uses] [INFERRED]
98→ --> .get() [method] [EXTRACTED]
99→ <-- __init__.py [imports] [EXTRACTED]
100→ ...
101→
102→$ graphify path "FastAPI" "ModelField"
103→Shortest path (3 hops):
104→ FastAPI --uses--> DefaultPlaceholder <--references-- get_request_handler() --references--> ModelField
105→```
106→
107→Every edge carries a **confidence tag** (`EXTRACTED` = explicit in the source, `INFERRED` = derived by resolution), so you can tell what was read directly from what was inferred. `graphify query "<question>"` returns a scoped subgraph for a plain-language question, and `graphify path A B` traces how any two things connect.
108→
109→---
110→
111→## What it does
112→
113→What you get out of the box:
114→
115→| Capability | What you get |
116→|---|---|
117→| **God nodes** | The most-connected concepts, so you see what everything flows through |
118→| **Communities** | The graph split into subsystems (Leiden), with LLM-free labels |
119→| **Cross-file links** | `calls` / `imports` / `inherits` / `mixes_in` resolved across ~40 languages via tree-sitter AST |
120→| **Query, path, explain** | Ask a question, trace the path between two things, or explain one concept, all against `graph.json` |
121→| **Rationale + doc refs** | `# NOTE:` / `# WHY:` comments and ADR/RFC citations become first-class nodes linked to the code |
122→| **Beyond code** | Docs, PDFs, images, and video/audio all map into the same graph |
123→| **Local-first** | Code is parsed locally with tree-sitter (no LLM, nothing leaves your machine); only the semantic pass over docs/media calls a backend, and only if you configure one |
124→
125→> [!TIP]
126→> Running this across many repos or a monorepo? [Graphify Cloud](https://app.graphify.com/login) does it continuously and cuts agent token spend by 80%, with cross-repo links, SDLC-wide code review, formal verification, and Sentry/Jira connectors. [Start a free 14-day trial &rarr;](https://app.graphify.com/login)
127→
128→---
129→
130→## Benchmarks: 0.497 recall@10, 0 LLM credits
131→
132→| Benchmark | Metric | graphify | Field |
133→|---|---|---|---|
134→| LOCOMO (n=300) | recall@10 | **0.497** | mem0 0.048, supermemory 0.149 |
135→| LOCOMO (n=300) | QA accuracy | 45.3% | supermemory 49.7%, mem0 27.3% |
136→| LongMemEval-S (n=50) | QA accuracy | **76%** | tied with dense RAG |
137→| ERPNext cross-tool (n=6) | key-fact coverage | **82.0%** | grep/read baseline 70.8% |
138→| Graph build | LLM credits | **0** | per-token for most systems |
139→
140→Every system ran on the same harness with the same model and budgets, scored by a judge blind-validated against a second judge (90.6% agreement, Cohen's kappa 0.81). Full per-system tables, the code-intelligence result, and reproduction commands: **[BENCHMARKS.md](./BENCHMARKS.md)**.
141→
142→---
143→
144→## Documentation
145→
146→Full guides and reference live at **[docs.graphify.com](https://docs.graphify.com)**:
147→
148→- **[Quickstart](https://docs.graphify.com/quickstart)**: build your first graph
149→- **[CLI reference](https://docs.graphify.com/reference/overview)**: every command and flag
150→- **[Ask better graph questions](https://docs.graphify.com/guides/querying)**: querying patterns
151→- **[Configuration](https://docs.graphify.com/reference/configuration)**: environment variables and tuning
152→- **[Supported inputs](https://docs.graphify.com/concepts/supported-inputs)**: languages and file types
153→- **[Team workflows](https://docs.graphify.com/guides/team-workflows)** and **[PR review](https://docs.graphify.com/guides/pull-requests)**
154→- **[Troubleshooting](https://docs.graphify.com/troubleshooting)** and **[How it works](https://docs.graphify.com/concepts/architecture)**
155→
156→---
157→
158→## Prerequisites
159→
160→| Requirement | Minimum | Check | Install |
161→|---|---|---|---|
162→| Python | 3.10+ | `python --version` | [python.org](https://www.python.org/downloads/) |
163→| uv *(recommended)* | any | `uv --version` | `curl -LsSf https://astral.sh/uv/install.sh \| sh` |
164→| pipx *(alternative)* | any | `pipx --version` | `pip install pipx` |
165→
166→**macOS quick install (Homebrew):**
167→```bash
168→brew install python@3.12 uv
169→```
170→
171→**Windows quick install:**
172→```powershell
173→winget install astral-sh.uv
174→```
175→
176→**Ubuntu/Debian:**
177→```bash
178→sudo apt install python3.12 python3-pip pipx
179→# or install uv:
180→curl -LsSf https://astral.sh/uv/install.sh | sh
181→```
182→
183→---
184→
185→## Install
186→
187→> [!IMPORTANT]
188→> **Official package:** The PyPI package is `graphifyy` (double-y). Other `graphify*` packages on PyPI are not affiliated. The CLI command is still `graphify`.
189→
190→The official source repository is [Graphify-Labs/graphify](https://github.com/Graphify-Labs/graphify).
191→
192→The two-command quickstart is at the top of this README. This section covers the install methods, project-scoped installs, and every supported platform.
193→
194→**Install methods** (pick one):
195→
196→```bash
197→uv tool install graphifyy # recommended, isolated env (if 'graphify' isn't found after, run: uv tool update-shell)
198→pipx install graphifyy # alternative
199→pip install graphifyy # may need PATH setup, see Troubleshooting below
200→```
201→
202→Then run `graphify install` once. It detects which assistant you run and registers the skill, so there is no per-assistant setup. Open your AI assistant and type `/graphify .`
203→
204→To install the assistant skill into the current repository instead of your user
205→profile, add `--project`:
206→
207→```bash
208→graphify install --project
209→graphify install --project --platform codex
210→```
211→
212→Project-scoped installs write under the current directory, for example
213→`.claude/skills/graphify/SKILL.md` or `.agents/skills/graphify/SKILL.md` (plus a
214→`references/` sidecar the skill loads on demand), and
215→print a `git add` hint for files that can be committed.
216→Per-platform commands that support project-scoped installs accept the same flag,
217→for example `graphify claude install --project` or `graphify codex install --project`.
218→
219→> [!TIP]
220→> Hitting `command not found`, a `pip`-on-Mac/Windows issue, PowerShell quoting, `uvx` usage, git-hook PATH quirks, or strict mode? See **[Installation](https://docs.graphify.com/installation)** and **[Troubleshooting](https://docs.graphify.com/troubleshooting)**.
221→
222→<details>
223→<summary><b>Pick your platform</b> (20+ assistants, click to expand)</summary>
224→
225→| Platform | Install command |
226→|----------|----------------|
227→| Claude Code (Linux/Mac) | `graphify install` |
228→| Claude Code (Windows) | `graphify install` (auto-detected) or `graphify install --platform windows` |
229→| CodeBuddy | `graphify install --platform codebuddy` |
230→| Codex | `graphify install --platform codex` |
231→| OpenCode | `graphify install --platform opencode` |
232→| Kilo Code | `graphify install --platform kilo` |
233→| GitHub Copilot CLI | `graphify install --platform copilot` |
234→| VS Code Copilot Chat | `graphify vscode install` |
235→| Aider | `graphify install --platform aider` |
236→| OpenClaw | `graphify install --platform claw` |
237→| Factory Droid | `graphify install --platform droid` |
238→| Trae | `graphify install --platform trae` |
239→| Trae CN | `graphify install --platform trae-cn` |
240→| Gemini CLI | `graphify install --platform gemini` |
241→| Hermes | `graphify install --platform hermes` |
242→| Kimi Code | `graphify install --platform kimi` |
243→| Amp | `graphify amp install` |
244→| Agent Skills (cross-framework) | `graphify install --platform agents` (alias `--platform skills`) |
245→| Kiro IDE/CLI | `graphify kiro install` |
246→| Pi coding agent | `graphify install --platform pi`, plus `graphify pi guard install` for the native guard |
247→| Cursor | `graphify cursor install` |
248→| Devin CLI | `graphify devin install` |
249→| Google Antigravity | `graphify antigravity install` |
250→| Google Antigravity (Windows) | `graphify antigravity install` (auto-detected on Windows) |
251→
252→Codex users also need `multi_agent = true` under `[features]` in `~/.codex/config.toml` for parallel extraction. CodeBuddy uses the same Agent tool and PreToolUse hook mechanism as Claude Code. Factory Droid uses the `Task` tool for parallel subagent dispatch. OpenClaw and Aider use sequential extraction (parallel agent support is still early on those platforms). Trae uses the Agent tool for parallel subagent dispatch and does **not** support `PreToolUse` hooks, so AGENTS.md is the always-on mechanism.
253→
254→`--platform agents` (alias `--platform skills`) targets the generic cross-framework [Agent-Skills](https://github.com/anthropics/skills) locations: the spec's user-global `~/.agents/skills/` (read by `npx skills` and spec-compliant frameworks) for a global install, and `./.agents/skills/` for a project (`--project`) install. The bare `graphify install` stays single-platform (Claude Code) by design: use the named `agents` platform when you want the skill discoverable by any framework that reads `.agents/skills`.
255→
256→Pi has no `PreToolUse` hook, so `graphify pi guard install` registers a native Pi extension (via Pi's own `pi install <package directory>`) that runs the installed `graphify hook-guard` before Pi's `read`, `grep`, `find` and search-style `bash` calls. Fresh/stale graph decisions and the `GRAPHIFY_HOOK_STRICT=1` once-per-session indexed-read denial come from that same policy, so Pi matches Claude Code's hook behavior; guidance arrives as a `<system-reminder source="graphify">` steering message. It needs Pi 0.58.4 or newer: earlier versions let a steering message skip the rest of a parallel tool-call batch. The package ships inside the Graphify installation, so install Graphify persistently (`uv tool install graphifyy` or `pipx install graphifyy`, not `uvx`), restart Pi after installing or upgrading, and remove it with `graphify pi guard uninstall`. Only local file targets are inspected; the hook needs `graphify` on an absolute `PATH` entry outside the project, is bounded to a two-second, 256 KiB-in/64 KiB-out call, and fails open. The same package also loads in [Oh My Pi](https://github.com/can1357/oh-my-pi): `omp plugin install "$(graphify pi guard path)"`. The registered path contains the Python version and venv, so re-run `graphify pi guard install` after changing either, and remove the old entry with `pi remove <old path>`.
257→
258→> Codex uses `$graphify` instead of `/graphify`.
259→
260→</details>
261→
262→<details>
263→<summary><b>Optional extras</b> (install only what you need)</summary>
264→
265→| Extra | What it adds | Install |
266→|---|---|---|
267→| `pdf` | PDF extraction | `uv tool install "graphifyy[pdf]"` |
268→| `office` | `.docx` and `.xlsx` support | `uv tool install "graphifyy[office]"` |
269→| `google` | Google Sheets rendering | `uv tool install "graphifyy[google]"` |
270→| `video` | Video/audio transcription (faster-whisper + yt-dlp) | `uv tool install "graphifyy[video]"` |
271→| `mcp` | MCP stdio server | `uv tool install "graphifyy[mcp]"` |
272→| `watch` | Auto-rebuild on file changes (`graphify watch`) | `uv tool install "graphifyy[watch]"` |
273→| `neo4j` | Neo4j push support | `uv tool install "graphifyy[neo4j]"` |
274→| `falkordb` | FalkorDB push support | `uv tool install "graphifyy[falkordb]"` |
275→| `svg` | SVG graph export | `uv tool install "graphifyy[svg]"` |
276→| `leiden` | Leiden community detection (graspologic on Python < 3.13; native backend on 3.13+) | `uv tool install "graphifyy[leiden]"` |
277→| `ollama` | Ollama local inference | `uv tool install "graphifyy[ollama]"` |
278→| `openai` | OpenAI / OpenAI-compatible APIs | `uv tool install "graphifyy[openai]"` |
279→| `gemini` | Google Gemini API | `uv tool install "graphifyy[gemini]"` |
280→| `anthropic` | Anthropic Claude API (`--backend claude`, uses `ANTHROPIC_API_KEY`) | `uv tool install "graphifyy[anthropic]"` |
281→| `bedrock` | AWS Bedrock (uses IAM, no API key) | `uv tool install "graphifyy[bedrock]"` |
282→| `azure` | Azure OpenAI Service (`--backend azure`, uses `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_ENDPOINT`) | `uv tool install "graphifyy[openai]"` |
283→| `sql` | SQL schema extraction | `uv tool install "graphifyy[sql]"` |
284→| `postgres` | Live PostgreSQL introspection (`--postgres DSN`) | `uv tool install "graphifyy[postgres]"` |
285→| `dm` | BYOND DreamMaker `.dm`/`.dme` AST extraction (may need a C compiler + `python3-dev` if no wheel matches your platform) | `uv tool install "graphifyy[dm]"` |
286→| `terraform` | Terraform / HCL `.tf`/`.tfvars`/`.hcl` AST extraction | `uv tool install "graphifyy[terraform]"` |
287→| `pascal` | Pascal / Delphi `.pas`/`.dpr`/`.dpk`/`.inc` AST extraction (more accurate `calls`/`inherits` edges; falls back to a regex extractor when absent) | `uv tool install "graphifyy[pascal]"` |
288→| `ocaml` | OCaml `.ml`/`.mli` AST extraction | `uv tool install "graphifyy[ocaml]"` |
289→| `commonlisp` | Common Lisp `.lisp`/`.cl`/`.lsp`/`.asd` AST extraction | `uv tool install "graphifyy[commonlisp]"` |
290→| `robot` | Robot Framework `.robot`/`.resource` extraction (suites, test cases, keywords, keyword-call and resource/library import edges) | `uv tool install "graphifyy[robot]"` |
291→| `chinese` | Chinese query segmentation (jieba) | `uv tool install "graphifyy[chinese]"` |
292→| `all` | Everything above | `uv tool install "graphifyy[all]"` |
293→
294→</details>
295→
296→---
297→
298→## Make your assistant always use the graph
299→
300→Run this once in your project after building a graph:
301→
302→Run `graphify <platform> install` once in your project, for example `graphify claude install` or `graphify codex install` (or `graphify install --platform <name>`).
303→
304→This writes a small config file that tells your assistant to consult the knowledge graph for codebase questions, preferring scoped queries like `graphify query "<question>"` over reading the full report or grepping raw files.
305→
306→- **Hook platforms** (Claude Code, Gemini CLI): a hook fires automatically before search-style tool calls (and, on Claude Code, before reading source files one by one via the Read/Glob tools) and nudges your assistant toward the graph path.
307→- **Instruction-file platforms** (Codex, OpenCode, Cursor, etc.): persistent instruction files (`AGENTS.md`, `.cursor/rules/`, etc.) provide the same query-first guidance.
308→
309→`GRAPH_REPORT.md` is still available for broad architecture review.
310→
311→Exactly which files each platform writes (CodeBuddy's `CODEBUDDY.md` + `PreToolUse` hooks, Codex's `AGENTS.md`, Kilo's native `.kilo` plugin, Cursor's `alwaysApply` rule, and so on) is covered in **[Always-on setup](https://docs.graphify.com/guides/always-on)**.
312→
313→To remove graphify from all platforms at once: `graphify uninstall` (add `--purge` to also delete `graphify-out/`). Or use the per-platform command (e.g. `graphify claude uninstall`).
314→
315→### CLI skills or MCP instructions?
316→
317→The instructions installed by `graphify install` and those supplied with a Graphify MCP connection describe different ways to query a graph:
318→
319→| Setup | Guidance to use | Query access |
320→|---|---|---|
321→| Local CLI and installed assistant skill | The platform instructions written by `graphify install` | Run `graphify query`, `graphify path`, and `graphify explain` against the local graph (`graphify-out/` by default). |
322→| Connected Graphify MCP server | The connection's instructions and the tools listed by that server | Call the listed MCP tools against the graph served by that connection. Tool names and descriptions come from the server. |
323→
324→Both encourage scoped graph queries before broad source searches. Choose the instructions that match the tools your assistant can actually access; neither block establishes a universal precedence rule for your assistant's instruction files. If you use both integrations, identify which graph each queries and choose a primary query path instead of copying two unconditional instruction blocks into `AGENTS.md`.
325→
326→`graphify install` installs the local assistant integration; it does not establish an MCP connection. An MCP client does not need to run local CLI queries to use its connected server. A locally hosted server still needs its own Graphify installation and graph, while a hosted connection may serve a graph that is not present in the client's working directory. If the expected tools are missing, check the relevant CLI installation or MCP connection rather than treating the other setup's instructions as interchangeable.
327→
328→---
329→
330→## What's in the report
331→
332→`GRAPH_REPORT.md` summarizes the god nodes, communities, and key paths for broad architecture review. How the graph is built and what it contains: **[How graphify works](https://docs.graphify.com/concepts/architecture)**.
333→
334→---
335→
336→## What files it handles: ~40 languages
337→
338→graphify parses ~40 programming languages locally with tree-sitter AST, and maps docs, PDFs, images, and audio/video through an optional semantic pass. Full list: **[Supported inputs](https://docs.graphify.com/concepts/supported-inputs)**.
339→
340→---
341→
342→## Common commands
343→
344→```bash
345→/graphify . # build graph for current folder
346→/graphify ./docs --update # re-extract only changed files
347→/graphify . --cluster-only # rerun clustering without re-extracting
348→/graphify . --cluster-only --resolution 1.5 # more granular communities
349→/graphify . --cluster-only --exclude-hubs 99 # suppress utility super-hubs from god-node rankings
350→/graphify . --no-viz # skip the HTML, just the report + JSON
351→/graphify . --wiki # build a markdown wiki from the graph
352→graphify export callflow-html # Mermaid architecture/call-flow HTML (auto-regenerates on every git commit if hook is installed)
353→
354→/graphify query "what connects auth to the database?"
355→/graphify path "UserService" "DatabasePool"
356→/graphify explain "RateLimiter"
357→
358→/graphify add https://arxiv.org/abs/1706.03762 # fetch a paper and add it
359→/graphify add <youtube-url> # transcribe and add a video
360→
361→graphify hook install # auto-rebuild on commit + branch checkout (run `graphify update .` after `git pull`: see "Recommended workflow" below)
362→graphify merge-graphs a.json b.json # combine two graphs
363→
364→graphify prs # PR dashboard: CI state, review status, worktree mapping
365→graphify prs 42 # deep dive on PR #42 with graph impact
366→graphify prs --triage # AI ranks your review queue (uses whatever backend is configured)
367→graphify prs --conflicts # PRs sharing graph communities: merge-order risk
368→```
369→
370→See the [full command reference](#full-command-reference) below.
371→
372→---
373→
374→## Labeling and rendering limits
375→
376→- **`--batch-size`**: 100 communities per labeling call by default, sized for a ~16k-token context (~150 tokens/community). Use `--batch-size 40` for an 8k window. Context overflow is not split-retried; failed batches keep hub-derived names.
377→- **`--missing-only`**: `label --missing-only` keeps existing labels and names only unnamed / `Community N` entries. Use `label` (full relabel) to refresh names after the community set changes.
378→- **`.graphify_labels.json.sig`**: records the community membership signature; labels survive a re-cluster only while it matches.
379→- **`export html`**: 5,000-node default; above it graphify renders an aggregated community view. Use `--node-limit N`. `GRAPHIFY_VIZ_NODE_LIMIT` / `.graphifyrc` `viz_node_limit=N` apply to `cluster-only`, `update`, `watch`, and hooks, not `export html`.
380→- **Leiden fallback**: without the `leiden` extra, clustering silently uses networkx Louvain. Switching later reshuffles every community, so plan a full relabel.
381→
382→---
383→
384→## Ignoring files
385→
386→graphify honors `.gitignore` and supports `--exclude` patterns and a project `.graphifyignore`. Details: **[Configuration](https://docs.graphify.com/reference/configuration)**.
387→
388→
389→## Project configuration
390→
391→Create a `.graphifyrc` in the scan root for settings that belong to the project rather than to one run. One `key=value` per line; lines beginning with `#` are comments.
392→
393→**Ambiguous extensions.** Some extensions mean different languages in different projects: `.inc` is PHP on pfSense, Pascal in a Delphi tree, SQL or assembly elsewhere; `.h` is C or C++; `.m` is Objective-C or MATLAB. graphify has to pick one global default, and when it picks wrong the file does not fail: it parses as the wrong language and yields a handful of incidental nodes, so the graph looks populated while the real symbols are missing. Declare what the extension means in your repo:
394→
395→```
396→# .graphifyrc
397→# A language name:
398→language.inc=php
399→# Or an extension graphify already knows:
400→language.tpl=.ts
401→# Baked into the git hooks (see Team setup):
402→viz_node_limit=0
403→```
404→
405→The declaration flows through classification, extractor selection, grammar and resolution, imports, `graphify watch`, and the AST cache (a file re-parsed under a different language never reuses the old entry), and the same `.graphifyrc` is read by `extract`, `update`, the hooks, the MCP server, and the `/graphify` skill. A typo is reported once on stderr and the scan continues with the defaults. How declarations interact with caching, incremental rebuilds, and import resolution: **[Configuration](https://docs.graphify.com/reference/configuration)**.
406→
407→---
408→
409→## Team setup
410→
411→Commit or share the graph so your whole team queries the same context, and review pull requests with graph context. See **[Share context with your team](https://docs.graphify.com/guides/team-workflows)** and **[Review pull requests](https://docs.graphify.com/guides/pull-requests)**.
412→
413→---
414→
415→## Using the graph directly
416→
417→Beyond your AI assistant, query `graph.json` straight from the CLI with `graphify query`, `graphify path`, and `graphify explain`. A name that matches several nodes is refused with the candidates listed rather than guessed. Scripts can read the outcome from the exit code: `0` an answer, `3` an ambiguous name, `4` no matching node. See **[Ask better graph questions](https://docs.graphify.com/guides/querying)** and the **[query reference](https://docs.graphify.com/reference/query)**.
418→
419→---
420→
421→## Environment variables
422→
423→Backends, API keys, hook behavior, and tuning are controlled by environment variables. Full table: **[Configuration](https://docs.graphify.com/reference/configuration)**.
424→
425→- **Claude CLI model**: `GRAPHIFY_CLAUDE_CLI_MODEL` overrides the model for the `claude-cli` backend (default: Opus). `haiku` or `sonnet` are usually enough for community naming; the semantic extraction pass benefits from a larger model.
426→
427→---
428→
429→## Privacy
430→
431→- **Code files**: processed locally via tree-sitter. Nothing leaves your machine. A code-only corpus requires no API key: `graphify extract` runs fully offline. On a mixed repo, add `--code-only` to index just the code and skip the docs/PDFs/images that would otherwise need an LLM.
432→- **Video / audio**: transcribed locally with faster-whisper. Nothing leaves your machine.
433→- **Docs, PDFs, images**: sent to your AI assistant for semantic extraction (via the `/graphify` skill, using whatever model your IDE session runs). Headless `graphify extract` requires `GEMINI_API_KEY` / `GOOGLE_API_KEY` (Gemini), `MOONSHOT_API_KEY` (Kimi), `ANTHROPIC_API_KEY` (Claude), `OPENAI_API_KEY` (OpenAI), `DEEPSEEK_API_KEY` (DeepSeek), a running Ollama instance (`OLLAMA_BASE_URL`), AWS credentials via the standard provider chain (Bedrock - no API key needed, uses IAM), or the `claude` CLI binary (Claude Code - no API key needed, uses your Claude subscription). The `--dedup-llm` flag uses the same key.
434→- **Data residency**: `graphify extract` auto-detects which provider to use based on which API key is set (priority: Gemini → Kimi → Claude → OpenAI → DeepSeek → Azure → Bedrock → Ollama). When it auto-detects, it prints the exact environment variable that chose the provider, so a run is never a surprise. To choose explicitly, pass `--backend`, or set `GRAPHIFY_BACKEND=<name>`; set `GRAPHIFY_BACKEND=none` to disable all LLM backends (semantic extraction and the `claude -p` labeling fallback) and keep a code-only graph. For code with data-residency requirements, use `GRAPHIFY_BACKEND=ollama` / `--backend ollama` (fully local). Kimi (`MOONSHOT_API_KEY`) routes to Moonshot AI servers in China.
435→- **No telemetry**, no usage tracking, no analytics.
436→- **Query logging**: every `graphify query`, `graphify path`, `graphify explain`, and MCP `query_graph` call is logged to `~/.cache/graphify-queries.log` in JSON Lines format (timestamp, question, corpus, nodes returned, duration). Full subgraph responses are **not** stored by default. Set `GRAPHIFY_QUERY_LOG_DISABLE=1` to opt out, or `GRAPHIFY_QUERY_LOG=/dev/null` to silence without disabling the code path.
437→
438→---
439→
440→## Troubleshooting
441→
442→Common install and extraction issues and their fixes: **[Troubleshooting](https://docs.graphify.com/troubleshooting)**.
443→
444→---
445→
446→## Full command reference
447→
448→Every command and flag, with examples: **[CLI reference](https://docs.graphify.com/reference/overview)**.
449→
450→---
451→
452→## Learn more
453→
454→- [docs.graphify.com](https://docs.graphify.com): full documentation: guides, command reference, and integrations
455→- [How it works](docs/how-it-works.md): the extraction pipeline, community detection, confidence scoring, benchmarks
456→- [ARCHITECTURE.md](ARCHITECTURE.md): module breakdown, how to add a language
457→- [Optional integrations](docs/docker-mcp-sqlite.md): Docker MCP Toolkit + SQLite
458→- [The Memory Layer](https://safishamsi.gumroad.com/l/qetvlo): the book on the ideas behind graphify, the architecture end to end
459→
460→---
461→
462→## Graphify Cloud
463→
464→[**Graphify Cloud**](https://app.graphify.com/login) is the always-on layer built on top of graphify. Instead of a graph you rebuild on demand per folder, it keeps one live graph across your entire software development lifecycle:
465→
466→- **80% fewer tokens**: always-on memory means your agents stop re-reading and re-explaining the codebase every session.
467→- **Monorepo and cross-repo**: one connected graph across every service and repository, not a graph per folder.
468→- **Formal verification**: check architectural and dependency invariants against the live graph.
469→- **Code review with a bird's-eye view of your SDLC**: see how a change ripples across the whole system before you merge.
470→- **SDLC connectors**: pull in Sentry, Jira, and more, so incidents, tickets, and code live in one graph.
471→- **Always-on**: updates continuously in the background across code, docs, and meetings.
472→
473→**[Start a free 14-day trial at app.graphify.com &rarr;](https://app.graphify.com/login)**
474→
475→---
476→
477→## Contributing
478→
479→Contributions are welcome. See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the development setup, the test and CI-parity commands, the git workflow, and what makes a strong contribution (worked examples and extraction bug reports are the most useful). Architecture and how to add a language: [ARCHITECTURE.md](ARCHITECTURE.md).
480→
481→New here? Say hi on [Discord](https://discord.gg/graphify) or in [GitHub Discussions](https://github.com/Graphify-Labs/graphify/discussions).
482→
483→---
484→
485→## Contributors
486→
487→<a href="https://github.com/Graphify-Labs/graphify/graphs/contributors">
488→ <img src="https://contrib.rocks/image?repo=Graphify-Labs/graphify" alt="graphify contributors" />
489→</a>
490→
491→Made with [contrib.rocks](https://contrib.rocks).
492→
493→---
494→
495→## Translations
496→
497→The README is available in 32 languages. Use the language switcher at the top of this file to read it in yours, or browse [`docs/translations/`](docs/translations/). To improve a translation or add a new one, open a pull request against the matching file there.
498→
499→---
500→
501→## Building on graphify
502→
503→Building something in the graphify ecosystem? That is encouraged. If your project uses "graphify" in its name (for example `graphify-dashboard` or `graphify-action`), please add a short note to your README clarifying that it is community-built and not affiliated with or endorsed by Graphify Labs. "graphify" and the graphify logo are marks of Graphify Labs; please do not use them in a way that implies official status.
504→
505→---
506→
507→## Community and links
508→
509→<p align="center">
510→ <a href="https://graphify.com"><img src="https://img.shields.io/badge/Website-graphify.com-4c1?style=flat&logo=googlechrome&logoColor=white" alt="Website"/></a>
511→ <a href="https://discord.gg/graphify"><img src="https://img.shields.io/badge/Discord-Join-5865F2?style=flat&logo=discord&logoColor=white" alt="Discord"/></a>
512→ <a href="https://x.com/graphify"><img src="https://img.shields.io/badge/X-graphify-000000?logo=x&logoColor=white" alt="X"/></a>
513→ <a href="https://www.youtube.com/@graphifylabs"><img src="https://img.shields.io/badge/YouTube-Graphify%20Labs-FF0000?style=flat&logo=youtube&logoColor=white" alt="YouTube"/></a>
514→ <a href="https://github.com/sponsors/safishamsi"><img src="https://img.shields.io/badge/sponsor-safishamsi-ea4aaa?logo=github-sponsors" alt="Sponsor"/></a>
515→ <a href="https://safishamsi.gumroad.com/l/qetvlo"><img src="https://img.shields.io/badge/Book-The%20Memory%20Layer-2ea44f?style=flat&logo=gitbook&logoColor=white" alt="The Memory Layer"/></a>
516→</p>
517→
-426
View File
@@ -1,426 +0,0 @@
Initializing deployment
Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
remote: Enumerating objects: 1836, done.
remote: Counting objects: 0% (1/1836) remote: Counting objects: 1% (19/1836) remote: Counting objects: 2% (37/1836) remote: Counting objects: 3% (56/1836) remote: Counting objects: 4% (74/1836) remote: Counting objects: 5% (92/1836) remote: Counting objects: 6% (111/1836) remote: Counting objects: 7% (129/1836) remote: Counting objects: 8% (147/1836) remote: Counting objects: 9% (166/1836) remote: Counting objects: 10% (184/1836) remote: Counting objects: 11% (202/1836) remote: Counting objects: 12% (221/1836) remote: Counting objects: 13% (239/1836) remote: Counting objects: 14% (258/1836) remote: Counting objects: 15% (276/1836) remote: Counting objects: 16% (294/1836) remote: Counting objects: 17% (313/1836) remote: Counting objects: 18% (331/1836) remote: Counting objects: 19% (349/1836) remote: Counting objects: 20% (368/1836) remote: Counting objects: 21% (386/1836) remote: Counting objects: 22% (404/1836) remote: Counting objects: 23% (423/1836) remote: Counting objects: 24% (441/1836) remote: Counting objects: 25% (459/1836) remote: Counting objects: 26% (478/1836) remote: Counting objects: 27% (496/1836) remote: Counting objects: 28% (515/1836) remote: Counting objects: 29% (533/1836) remote: Counting objects: 30% (551/1836) remote: Counting objects: 31% (570/1836) remote: Counting objects: 32% (588/1836) remote: Counting objects: 33% (606/1836) remote: Counting objects: 34% (625/1836) remote: Counting objects: 35% (643/1836) remote: Counting objects: 36% (661/1836) remote: Counting objects: 37% (680/1836) remote: Counting objects: 38% (698/1836) remote: Counting objects: 39% (717/1836) remote: Counting objects: 40% (735/1836) remote: Counting objects: 41% (753/1836) remote: Counting objects: 42% (772/1836) remote: Counting objects: 43% (790/1836) remote: Counting objects: 44% (808/1836) remote: Counting objects: 45% (827/1836) remote: Counting objects: 46% (845/1836) remote: Counting objects: 47% (863/1836) remote: Counting objects: 48% (882/1836) remote: Counting objects: 49% (900/1836) remote: Counting objects: 50% (918/1836) remote: Counting objects: 51% (937/1836) remote: Counting objects: 52% (955/1836) remote: Counting objects: 53% (974/1836) remote: Counting objects: 54% (992/1836) remote: Counting objects: 55% (1010/1836) remote: Counting objects: 56% (1029/1836) remote: Counting objects: 57% (1047/1836) remote: Counting objects: 58% (1065/1836) remote: Counting objects: 59% (1084/1836) remote: Counting objects: 60% (1102/1836) remote: Counting objects: 61% (1120/1836) remote: Counting objects: 62% (1139/1836) remote: Counting objects: 63% (1157/1836) remote: Counting objects: 64% (1176/1836) remote: Counting objects: 65% (1194/1836) remote: Counting objects: 66% (1212/1836) remote: Counting objects: 67% (1231/1836) remote: Counting objects: 68% (1249/1836) remote: Counting objects: 69% (1267/1836) remote: Counting objects: 70% (1286/1836) remote: Counting objects: 71% (1304/1836) remote: Counting objects: 72% (1322/1836) remote: Counting objects: 73% (1341/1836) remote: Counting objects: 74% (1359/1836) remote: Counting objects: 75% (1377/1836) remote: Counting objects: 76% (1396/1836) remote: Counting objects: 77% (1414/1836) remote: Counting objects: 78% (1433/1836) remote: Counting objects: 79% (1451/1836) remote: Counting objects: 80% (1469/1836) remote: Counting objects: 81% (1488/1836) remote: Counting objects: 82% (1506/1836) remote: Counting objects: 83% (1524/1836) remote: Counting objects: 84% (1543/1836) remote: Counting objects: 85% (1561/1836) remote: Counting objects: 86% (1579/1836) remote: Counting objects: 87% (1598/1836) remote: Counting objects: 88% (1616/1836) remote: Counting objects: 89% (1635/1836) remote: Counting objects: 90% (1653/1836) remote: Counting objects: 91% (1671/1836) remote: Counting objects: 92% (1690/1836) remote: Counting objects: 93% (1708/1836) remote: Counting objects: 94% (1726/1836) remote: Counting objects: 95% (1745/1836) remote: Counting objects: 96% (1763/1836) remote: Counting objects: 97% (1781/1836) remote: Counting objects: 98% (1800/1836) remote: CounLine truncated
remote: Compressing objects: 0% (1/1379) remote: Compressing objects: 1% (14/1379) remote: Compressing objects: 2% (28/1379) remote: Compressing objects: 3% (42/1379) remote: Compressing objects: 4% (56/1379) remote: Compressing objects: 5% (69/1379) remote: Compressing objects: 6% (83/1379) remote: Compressing objects: 7% (97/1379) remote: Compressing objects: 8% (111/1379) remote: Compressing objects: 9% (125/1379) remote: Compressing objects: 10% (138/1379) remote: Compressing objects: 11% (152/1379) remote: Compressing objects: 12% (166/1379) remote: Compressing objects: 13% (180/1379) remote: Compressing objects: 14% (194/1379) remote: Compressing objects: 15% (207/1379) remote: Compressing objects: 16% (221/1379) remote: Compressing objects: 17% (235/1379) remote: Compressing objects: 18% (249/1379) remote: Compressing objects: 19% (263/1379) remote: Compressing objects: 20% (276/1379) remote: Compressing objects: 21% (290/1379) remote: Compressing objects: 22% (304/1379) remote: Compressing objects: 23% (318/1379) remote: Compressing objects: 24% (331/1379) remote: Compressing objects: 25% (345/1379) remote: Compressing objects: 26% (359/1379) remote: Compressing objects: 27% (373/1379) remote: Compressing objects: 28% (387/1379) remote: Compressing objects: 29% (400/1379) remote: Compressing objects: 30% (414/1379) remote: Compressing objects: 31% (428/1379) remote: Compressing objects: 32% (442/1379) remote: Compressing objects: 33% (456/1379) remote: Compressing objects: 34% (469/1379) remote: Compressing objects: 35% (483/1379) remote: Compressing objects: 36% (497/1379) remote: Compressing objects: 37% (511/1379) remote: Compressing objects: 38% (525/1379) remote: Compressing objects: 39% (538/1379) remote: Compressing objects: 40% (552/1379) remote: Compressing objects: 41% (566/1379) remote: Compressing objects: 42% (580/1379) remote: Compressing objects: 43% (593/1379) remote: Compressing objects: 44% (607/1379) remote: Compressing objects: 45% (621/1379) remote: Compressing objects: 46% (635/1379) remote: Compressing objects: 47% (649/1379) remote: Compressing objects: 48% (662/1379) remote: Compressing objects: 49% (676/1379) remote: Compressing objects: 50% (690/1379) remote: Compressing objects: 51% (704/1379) remote: Compressing objects: 52% (718/1379) remote: Compressing objects: 53% (731/1379) remote: Compressing objects: 54% (745/1379) remote: Compressing objects: 55% (759/1379) remote: Compressing objects: 56% (773/1379) remote: Compressing objects: 57% (787/1379) remote: Compressing objects: 58% (800/1379) remote: Compressing objects: 59% (814/1379) remote: Compressing objects: 60% (828/1379) remote: Compressing objects: 61% (842/1379) remote: Compressing objects: 62% (855/1379) remote: Compressing objects: 63% (869/1379) remote: Compressing objects: 64% (883/1379) remote: Compressing objects: 65% (897/1379) remote: Compressing objects: 66% (911/1379) remote: Compressing objects: 67% (924/1379) remote: Compressing objects: 68% (938/1379) remote: Compressing objects: 69% (952/1379) remote: Compressing objects: 70% (966/1379) remote: Compressing objects: 71% (980/1379) remote: Compressing objects: 72% (993/1379) remote: Compressing objects: 73% (1007/1379) remote: Compressing objects: 74% (1021/1379) remote: Compressing objects: 75% (1035/1379) remote: Compressing objects: 76% (1049/1379) remote: Compressing objects: 77% (1062/1379) remote: Compressing objects: 78% (1076/1379) remote: Compressing objects: 79% (1090/1379) remote: Compressing objects: 80% (1104/1379) remote: Compressing objects: 81% (1117/1379) remote: Compressing objects: 82% (1131/1379) remote: Compressing objects: 83% (1145/1379) remote: Compressing objects: 84% (1159/1379) remote: Compressing objects: 85% (1173/1379) remote: Compressing objects: 86% (1186/1379) remote: Compressing objects: 87% (1200/1379) remote: Compressing objects: 88% (1214/1379) remote: Compressing objects: 89% (1228/1379) remote: Compressing objects: 90% (1242/1379) remote: Compressing objects: 91% (1255/1379) remote: Compressing objects: 92% (1269/1379) remote: Compressing objects: 93% (1283/1379) remotLine truncated
Receiving objects: 0% (1/1836) Receiving objects: 1% (19/1836) Receiving objects: 2% (37/1836) Receiving objects: 3% (56/1836) Receiving objects: 4% (74/1836) Receiving objects: 5% (92/1836) Receiving objects: 6% (111/1836) Receiving objects: 7% (129/1836) Receiving objects: 8% (147/1836) Receiving objects: 9% (166/1836) Receiving objects: 10% (184/1836) Receiving objects: 11% (202/1836) Receiving objects: 12% (221/1836) Receiving objects: 13% (239/1836) Receiving objects: 14% (258/1836) Receiving objects: 15% (276/1836) Receiving objects: 16% (294/1836) Receiving objects: 17% (313/1836) Receiving objects: 18% (331/1836) Receiving objects: 19% (349/1836) Receiving objects: 20% (368/1836) Receiving objects: 21% (386/1836) Receiving objects: 22% (404/1836) Receiving objects: 23% (423/1836) Receiving objects: 24% (441/1836) Receiving objects: 25% (459/1836) Receiving objects: 26% (478/1836) Receiving objects: 27% (496/1836) Receiving objects: 28% (515/1836) Receiving objects: 29% (533/1836) Receiving objects: 30% (551/1836) Receiving objects: 31% (570/1836) Receiving objects: 32% (588/1836) Receiving objects: 33% (606/1836) Receiving objects: 34% (625/1836) Receiving objects: 35% (643/1836) Receiving objects: 36% (661/1836) Receiving objects: 37% (680/1836) Receiving objects: 38% (698/1836) Receiving objects: 39% (717/1836) Receiving objects: 40% (735/1836) Receiving objects: 41% (753/1836) Receiving objects: 42% (772/1836) Receiving objects: 43% (790/1836) Receiving objects: 44% (808/1836) Receiving objects: 45% (827/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 46% (845/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 47% (863/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 48% (882/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 49% (900/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 50% (918/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 51% (937/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 52% (955/1836), 14.90 MiB | 29.78 MiB/s Receiving objects: 52% (973/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 53% (974/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 54% (992/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 55% (1010/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 56% (1029/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 57% (1047/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 58% (1065/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 59% (1084/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 60% (1102/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 61% (1120/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 62% (1139/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 63% (1157/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 64% (1176/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 65% (1194/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 66% (1212/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 67% (1231/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 68% (1249/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 69% (1267/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 70% (1286/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 71% (1304/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 72% (1322/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 73% (1341/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 74% (1359/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 75% (1377/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 76% (1396/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 77% (1414/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 78% (1433/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 79% (1451/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 80% (1469/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 81% (1488/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 82% (1506/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 83% (1524/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 84% (1543/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 85% (1561/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 86% (1579/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 87% (1598/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 88% (1616/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 89% (1635/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 90% (1653/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 91% (1671/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 92% (1690/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 93% (1708/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 94% (1726/1836), 30.91 MiB | 30.91 MiB/s Receiving objects: 95% (1745/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 96% (1763/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 97% (1781/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 98% (1800/1836), 47.46 MiB | 31.63 MiB/s Receiving objects: 99% (1818/1836), 47.46 MiB | 31.63 MiB/s remote: Total 1836 (delta Line truncated
Receiving objects: 100% (1836/1836), 47.46 MiB | 31.63 MiB/s␍Receiving objects: 100% (1836/1836), 47.65 MiB | 31.60 MiB/s, done.
Resolving deltas: 0% (0/316)␍Resolving deltas: 1% (4/316)␍Resolving deltas: 2% (7/316)␍Resolving deltas: 3% (10/316)␍Resolving deltas: 4% (13/316)␍Resolving deltas: 5% (16/316)␍Resolving deltas: 6% (19/316)␍Resolving deltas: 7% (23/316)␍Resolving deltas: 8% (26/316)␍Resolving deltas: 9% (29/316)␍Resolving deltas: 10% (32/316)␍Resolving deltas: 11% (35/316)␍Resolving deltas: 12% (38/316)␍Resolving deltas: 13% (42/316)␍Resolving deltas: 14% (45/316)␍Resolving deltas: 15% (48/316)␍Resolving deltas: 16% (51/316)␍Resolving deltas: 17% (54/316)␍Resolving deltas: 18% (57/316)␍Resolving deltas: 19% (61/316)␍Resolving deltas: 20% (64/316)␍Resolving deltas: 21% (67/316)␍Resolving deltas: 22% (70/316)␍Resolving deltas: 23% (73/316)␍Resolving deltas: 24% (76/316)␍Resolving deltas: 25% (79/316)␍Resolving deltas: 26% (83/316)␍Resolving deltas: 27% (86/316)␍Resolving deltas: 28% (89/316)␍Resolving deltas: 29% (92/316)␍Resolving deltas: 30% (95/316)␍Resolving deltas: 31% (98/316)␍Resolving deltas: 32% (102/316)␍Resolving deltas: 33% (105/316)␍Resolving deltas: 34% (108/316)␍Resolving deltas: 35% (111/316)␍Resolving deltas: 36% (114/316)␍Resolving deltas: 37% (117/316)␍Resolving deltas: 38% (121/316)␍Resolving deltas: 39% (124/316)␍Resolving deltas: 40% (127/316)␍Resolving deltas: 41% (130/316)␍Resolving deltas: 42% (133/316)␍Resolving deltas: 43% (136/316)␍Resolving deltas: 44% (140/316)␍Resolving deltas: 45% (143/316)␍Resolving deltas: 46% (146/316)␍Resolving deltas: 47% (149/316)␍Resolving deltas: 48% (152/316)␍Resolving deltas: 49% (155/316)␍Resolving deltas: 50% (159/316)␍Resolving deltas: 51% (162/316)␍Resolving deltas: 52% (165/316)␍Resolving deltas: 53% (168/316)␍Resolving deltas: 54% (171/316)␍Resolving deltas: 55% (174/316)␍Resolving deltas: 56% (177/316)␍Resolving deltas: 57% (182/316)␍Resolving deltas: 58% (184/316)␍Resolving deltas: 59% (188/316)␍Resolving deltas: 60% (190/316)␍Resolving deltas: 61% (193/316)␍Resolving deltas: 62% (196/316)␍Resolving deltas: 63% (200/316)␍Resolving deltas: 64% (203/316)␍Resolving deltas: 65% (206/316)␍Resolving deltas: 66% (209/316)␍Resolving deltas: 67% (213/316)␍Resolving deltas: 68% (215/316)␍Resolving deltas: 69% (219/316)␍Resolving deltas: 70% (222/316)␍Resolving deltas: 71% (225/316)␍Resolving deltas: 72% (229/316)␍Resolving deltas: 73% (231/316)␍Resolving deltas: 74% (234/316)␍Resolving deltas: 75% (237/316)␍Resolving deltas: 76% (241/316)␍Resolving deltas: 77% (244/316)␍Resolving deltas: 78% (247/316)␍Resolving deltas: 79% (250/316)␍Resolving deltas: 80% (253/316)␍Resolving deltas: 81% (256/316)␍Resolving deltas: 82% (260/316)␍Resolving deltas: 83% (263/316)␍Resolving deltas: 84% (267/316)␍Resolving deltas: 85% (269/316)␍Resolving deltas: 86% (272/316)␍Resolving deltas: 87% (276/316)␍Resolving deltas: 88% (279/316)␍Resolving deltas: 89% (282/316)␍Resolving deltas: 90% (285/316)␍Resolving deltas: 91% (288/316)␍Resolving deltas: 92% (291/316)␍Resolving deltas: 93% (294/316)␍Resolving deltas: 94% (298/316)␍Resolving deltas: 95% (301/316)␍Resolving deltas: 96% (304/316)␍Resolving deltas: 97% (307/316)␍Resolving deltas: 98% (310/316)␍Resolving deltas: 99% (313/316)␍Resolving deltas: 100% (316/316)␍Resolving deltas: 100% (316/316), done.
> Installing railpack, please wait…
____ _ _ _
| _ \ __ _(_) |_ __ __ _ ___| | __
| |_) / _` | | | '_ \ / _` |/ __| |/ /
| _ < (_| | | | |_) | (_| | (__| <
|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
|_|
Railpack is now installed!
Run 'railpack --help' to get started
railpack-dfm-aos-lgbcnc-INtHrR
Preparing Railpack build plan...
╭─────────────────╮
│ Railpack 0.15.4 │
╰─────────────────╯
↳ Detected Node
↳ Using bun package manager
Packages
──────────
bun │ 1.4.4 │ railpack default (latest)
node │ 26.12.1 │ railpack default (latest)
Steps
──────────
▸ install
$ bun install --frozen-lockfile
▸ build
$ bun run build
Deploy
──────────
$ bun run start
✅ Railpack prepare completed.
Building with Railpack frontend...
#0 building with "railpack-dfm-aos-lgbcnc-INtHrR" instance using docker-container driver
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 1.1s done
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-inthrr0
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-inthrr0 0.6s done
#1 DONE 1.7s
#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
#2 DONE 1.4s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 0.0s done
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 2.10MB / 7.90MB 0.3s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.4s done
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.5s done
#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
#3 DONE 0.7s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.1s done
#3 DONE 0.8s
#4 load build definition from railpack-plan.json
#4 transferring dockerfile: 5.11kB done
#4 DONE 0.0s
#5 [railpack] secrets hash
#5 DONE 0.0s
#6 loading .
#6 DONE 0.0s
#7 [railpack] loading secrets
#7 resolve docker.io/library/alpine:latest
#7 ...
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 resolve ghcr.io/railwayapp/railpack-builder:latest 0.9s done
#8 DONE 1.0s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 0B / 119B 0.2s
#8 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0B / 868.40kB 0.2s
#8 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.3s done
#8 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.3s done
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 0B / 237.08MB 0.2s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 0B / 53.72MB 0.2s
#8 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 0B / 32B 0.2s
#8 ...
#5 [railpack] secrets hash
#5 DONE 0.0s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.2s done
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 0B / 67.81MB 0.2s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 7.34MB / 53.72MB 0.5s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 0B / 25.64MB 0.2s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 17.83MB / 237.08MB 0.6s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 7.34MB / 67.81MB 0.5s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 14.68MB / 53.72MB 0.8s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 6.29MB / 25.64MB 0.5s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 30.41MB / 237.08MB 0.9s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 14.68MB / 67.81MB 0.8s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 10.49MB / 25.64MB 0.6s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 18.87MB / 53.72MB 1.1s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 14.68MB / 25.64MB 0.8s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 17.83MB / 25.64MB 0.9s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 48.23MB / 237.08MB 1.4s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 23.07MB / 53.72MB 1.4s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 22.02MB / 67.81MB 1.1s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 23.07MB / 25.64MB 1.1s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 26.21MB / 53.72MB 1.5s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 29.36MB / 67.81MB 1.4s
#8 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 1.3s done
#8 ...
#7 [railpack] loading secrets
#7 resolve docker.io/library/alpine:latest 1.5s done
#7 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.9s done
#7 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 0.5s done
#7 DONE 2.9s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 30.15MB / 53.72MB 1.7s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 69.21MB / 237.08MB 1.8s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 35.65MB / 67.81MB 1.5s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 0B / 49.39MB 0.2s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 35.65MB / 53.72MB 2.0s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 40.89MB / 67.81MB 1.7s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 6.29MB / 49.39MB 0.5s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 83.89MB / 237.08MB 2.1s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 40.89MB / 53.72MB 2.3s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 48.23MB / 67.81MB 2.0s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 10.49MB / 49.39MB 0.6s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 97.52MB / 237.08MB 2.4s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 52.43MB / 67.81MB 2.1s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 14.68MB / 49.39MB 0.8s
#8 ...
#9 [railpack] copy secrets hash
#9 DONE 0.7s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 18.87MB / 49.39MB 0.9s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 46.14MB / 53.72MB 2.6s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 23.07MB / 49.39MB 1.1s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 111.15MB / 237.08MB 2.7s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 59.77MB / 67.81MB 2.4s
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 51.38MB / 53.72MB 2.9s
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 63.96MB / 67.81MB 2.6s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 30.41MB / 49.39MB 1.4s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 126.88MB / 237.08MB 3.0s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 36.70MB / 49.39MB 1.5s
#8 ...
#10 [railpack] hash used secrets
#10 DONE 0.7s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 3.2s done
#8 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 2.9s done
#8 ...
#11 [railpack] copy used secrets hash
#11 DONE 0.0s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 145.75MB / 237.08MB 3.3s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 40.89MB / 49.39MB 1.7s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 46.14MB / 49.39MB 1.8s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 168.15MB / 237.08MB 3.6s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.0s
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 181.40MB / 237.08MB 3.8s
#8 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.2s done
#8 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 205.52MB / 237.08MB 4.1s
#8 ...
#6 loading .
#6 transferring context: 127.67MB 3.8s done
#6 DONE 4.0s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 231.05MB / 237.08MB 4.4s
#8 ...
#12 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#12 resolve ghcr.io/railwayapp/railpack-runtime:latest 0.9s done
#12 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.3s done
#12 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 0.7s done
#12 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 3.4s done
#12 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.6s done
#12 DONE 5.6s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 4.7s done
#8 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 2.7s done
#8 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
#8 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.7s done
#8 DONE 9.4s
#13 install apt packages: libatomic1
#13 0.232 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
#13 0.314 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#13 0.345 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#13 0.374 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
#13 0.549 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
#13 0.575 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
#13 2.260 Fetched 10.2 MB in 2s (4830 kB/s)
#13 2.260 Reading package lists...
#13 4.151 Reading package lists...
#13 5.983 Building dependency tree...
#13 6.439 Reading state information...
#13 6.939 The following NEW packages will be installed:
#13 6.941 libatomic1
#13 7.101 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
#13 7.101 Need to get 9308 B of archives.
#13 7.101 After this operation, 46.1 kB of additional disk space will be used.
#13 7.101 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
#13 7.542 debconf: unable to initialize frontend: Dialog
#13 7.543 debconf: (TERM is not set, so the dialog frontend is not usable.)
#13 7.543 debconf: falling back to frontend: Readline
#13 7.543 debconf: unable to initialize frontend: Readline
#13 7.543 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
#13 7.543 debconf: falling back to frontend: Teletype
#13 7.550 debconf: unable to initialize frontend: Teletype
#13 7.550 debconf: (This frontend requires a controlling tty.)
#13 7.550 debconf: falling back to frontend: Noninteractive
#13 ...
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 4.6s done
#8 DONE 14.0s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
#8 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
#8 ...
#13 install apt packages: libatomic1
#13 8.681 Fetched 9308 B in 0s (65.4 kB/s)
#13 8.727 Selecting previously unselected package libatomic1:amd64.
#13 8.727 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
#13 8.735 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
#13 8.756 Unpacking libatomic1:amd64 (14.2.0-19) ...
#13 8.817 Setting up libatomic1:amd64 (14.2.0-19) ...
#13 8.823 Processing triggers for libc-bin (2.41-12+deb13u4) ...
#13 DONE 9.4s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.1s done
#8 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
#8 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 7.1s done
#8 DONE 22.2s
#8 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#8 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
#8 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
#8 DONE 22.2s
#14 mkdir /etc/mise
#14 DONE 1.5s
#15 create mise config
#15 DONE 0.0s
#16 install mise packages: bun, node
#16 0.142 mise by @jdx – installing 2 tools
#16 3.151 mise ███████████░░░░░ 0/2 · 3.0s
#16 3.151 bun@1.4.4 downloading 2.7s 51.8/51.8 MB · 22.0 MB/s
#16 3.151 node@26.12.1 downloading 2.7s 62.1/62.9 MB · 24.6 MB/s
#16 3.856 mise bun@1.4.4 1.4.4
#16 3.869 mise ✓ bun@1.4.4 3.4s bun-linux-x64.zip
#16 4.708 mise node@26.12.1 v26.12.1
#16 4.828 mise node@26.12.1 11.20.0
#16 4.861 mise ✓ node@26.12.1 4.4s node-v26.12.1-linux-x64.tar.gz
#16 4.861 mise ████████████████ 2/2 · installed 2 tools in 4.7s
#16 DONE 5.7s
#17 mkdir -p /app/node_modules/.cache
#17 DONE 0.2s
#18 copy bun.lock
#18 DONE 0.0s
#19 copy package.json
#19 DONE 0.1s
#20 copy /mise/shims
#20 DONE 0.0s
#21 copy skills/podcast-generate/package.json
#21 DONE 0.0s
#22 copy skills/skill-finder-cn/package.json
#22 DONE 0.0s
#23 copy skills/stock-analysis-skill/package.json
#23 DONE 0.0s
#24 copy skills/storyboard-manager/package.json
#24 DONE 0.0s
#25 copy prisma
#25 DONE 0.0s
#26 bun install --frozen-lockfile
#26 0.115 bun install v1.4.4 (38afee6c8)
#26 ...
#27 copy /mise/installs
#27 ...
#26 bun install --frozen-lockfile
#26 14.31
#26 14.31 + @tailwindcss/postcss@4.1.18
#26 14.31 + @types/react@19.2.8
#26 14.31 + @types/react-dom@19.2.3
#26 14.31 + bun-types@1.3.6
#26 14.31 + eslint@9.39.2
#26 14.31 + eslint-config-next@16.1.3
#26 14.31 + tailwindcss@4.1.18
#26 14.31 + tw-animate-css@1.4.0
#26 14.31 + typescript@5.9.3
#26 14.31 + @dnd-kit/core@6.3.1
#26 14.31 + @dnd-kit/sortable@10.0.0
#26 14.31 + @dnd-kit/utilities@3.2.2
#26 14.31 + @hookform/resolvers@5.2.2
#26 14.31 + @hugeicons/core-free-icons@4.3.5
#26 14.31 + @hugeicons/react@1.1.10
#26 14.31 + @mdxeditor/editor@3.52.3
#26 14.31 + @prisma/client@6.19.2
#26 14.31 + @radix-ui/react-accordion@1.2.12
#26 14.31 + @radix-ui/react-alert-dialog@1.1.15
#26 14.31 + @radix-ui/react-aspect-ratio@1.1.8
#26 14.31 + @radix-ui/react-avatar@1.1.11
#26 14.31 + @radix-ui/react-checkbox@1.3.3
#26 14.31 + @radix-ui/react-collapsible@1.1.12
#26 14.31 + @radix-ui/react-context-menu@2.2.16
#26 14.31 + @radix-ui/react-dialog@1.1.15
#26 14.31 + @radix-ui/react-dropdown-menu@2.1.16
#26 14.31 + @radix-ui/react-hover-card@1.1.15
#26 14.31 + @radix-ui/react-label@2.1.8
#26 14.31 + @radix-ui/react-menubar@1.1.16
#26 14.31 + @radix-ui/react-navigation-menu@1.2.14
#26 14.31 + @radix-ui/react-popover@1.1.15
#26 14.31 + @radix-ui/react-progress@1.1.8
#26 14.31 + @radix-ui/react-radio-group@1.3.8
#26 14.31 + @radix-ui/react-scroll-area@1.2.10
#26 14.31 + @radix-ui/react-select@2.2.6
#26 14.31 + @radix-ui/react-separator@1.1.8
#26 14.31 + @radix-ui/react-slider@1.3.6
#26 14.31 + @radix-ui/react-slot@1.2.4
#26 14.31 + @radix-ui/react-switch@1.2.6
#26 14.31 + @radix-ui/react-tabs@1.1.13
#26 14.31 + @radix-ui/react-toast@1.2.15
#26 14.31 + @radix-ui/react-toggle@1.1.10
#26 14.31 + @radix-ui/react-toggle-group@1.1.11
#26 14.31 + @radix-ui/react-tooltip@1.2.8
#26 14.31 + @reactuses/core@6.1.9
#26 14.31 + @tanstack/react-query@5.90.19
#26 14.31 + @tanstack/react-table@8.21.3
#26 14.31 + class-variance-authority@0.7.1
#26 14.31 + clsx@2.1.1
#26 14.31 + cmdk@1.1.1
#26 14.31 + date-fns@4.1.0
#26 14.31 + embla-carousel-react@8.6.0
#26 14.31 + framer-motion@14.7.1
#26 14.31 + imapflow@2.9.1
#26 14.31 + input-otp@1.4.2
#26 14.31 + lucide-react@1.62.0
#26 14.31 + motion@12.43.0
#26 14.31 + next@16.1.3
#26 14.31 + next-auth@4.24.13
#26 14.31 + next-intl@4.7.0
#26 14.31 + next-themes@0.4.6
#26 14.31 + prisma@6.19.2
#26 14.31 + react@19.2.3
#26 14.31 + react-day-picker@9.13.0
#26 14.31 + react-dom@19.2.3
#26 14.31 + react-hook-form@7.71.1
#26 14.31 + react-markdown@10.1.0
#26 14.31 + react-resizable-panels@3.0.6
#26 14.31 + react-syntax-highlighter@15.6.6
#26 14.31 + recharts@2.15.4
#26 14.31 + sharp@0.34.5
#26 14.31 + sonner@2.0.7
#26 14.31 + tailwind-merge@3.7.0
#26 14.31 + tailwindcss-animate@1.0.7
#26 14.31 + uuid@11.1.0
#26 14.31 + vaul@1.1.2
#26 14.31 + z-ai-web-dev-sdk@0.0.18
#26 14.31 + zod@4.3.5
#26 14.31 + zustand@5.0.10
#26 14.31
#26 14.31 858 packages installed [14.19s]
#26 DONE 16.1s
#28 copy / /app
#28 ...
#27 copy /mise/installs
#27 DONE 7.3s
#29 copy /usr/local/bin/mise
#29 DONE 1.2s
#28 copy / /app
#28 ...
#30 copy /etc/mise/config.toml
#30 DONE 0.1s
#31 copy /root/.local/state/mise
#31 DONE 0.0s
#28 copy / /app
#28 DONE 2.7s
#32 bun run build
#32 0.169 $ next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
#32 0.359 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
#32 1.293 ▲ Next.js 16.1.3 (Turbopack)
#32 1.294 - Environments: .env
#32 1.294
#32 1.340 Creating an optimized production build ...
#32 13.17 (node:98) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#32 13.17 (Use `node --trace-deprecation ...` to show where the warning was created)
#32 31.57
#32 31.57 > Build error occurred
#32 31.57 Error: Turbopack build failed with 1 errors:
#32 31.57 ./node_modules/@prisma/client/index-browser.js:1:16
#32 31.57 Module not found: Can't resolve '.prisma/client/index-browser'
#32 31.57 > 1 | const prisma = require('.prisma/client/index-browser')
#32 31.57  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#32 31.57  2 |
#32 31.57  3 | module.exports = prisma
#32 31.57  4 |
#32 31.57
#32 31.57
#32 31.57
#32 31.57 Import trace:
#32 31.57 Client Component Browser:
#32 31.57 ./node_modules/@prisma/client/index-browser.js [Client Component Browser]
#32 31.57 ./src/lib/db.ts [Client Component Browser]
#32 31.57 ./src/components/aos/portal-shell.tsx [Client Component Browser]
#32 31.57 ./src/components/aos/app-shell.tsx [Client Component Browser]
#32 31.57 ./src/components/aos/app-shell.tsx [Server Component]
#32 31.57 ./src/app/page.tsx [Server Component]
#32 31.57
#32 31.57 https://nextjs.org/docs/messages/module-not-found
#32 31.57
#32 31.57
#32 31.57 at ./node_modules/ (prisma/client/index-browser.js:1:16)
#32 31.57 at <unknown> (https://nextjs.org/docs/messages/module-not-found)
#32 31.72 error: script "build" exited with code 1
#32 ERROR: process "bun run build" did not complete successfully: exit code: 1
------
> bun run build:
31.57 ./src/components/aos/app-shell.tsx [Client Component Browser]
31.57 ./src/components/aos/app-shell.tsx [Server Component]
31.57 ./src/app/page.tsx [Server Component]
31.57
31.57 https://nextjs.org/docs/messages/module-not-found
31.57
31.57
31.57 at ./node_modules/ (prisma/client/index-browser.js:1:16)
31.57 at <unknown> (https://nextjs.org/docs/messages/module-not-found)
31.72 error: script "build" exited with code 1
------
ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
❌ Railpack build failed
railpack-dfm-aos-lgbcnc-INtHrR removed
Error occurred ❌, check the logs for details.
-463
View File
@@ -1,463 +0,0 @@
Initializing deployment
Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
remote: Enumerating objects: 1876, done.
remote: Counting objects: 0% (1/1876) remote: Counting objects: 1% (19/1876) remote: Counting objects: 2% (38/1876) remote: Counting objects: 3% (57/1876) remote: Counting objects: 4% (76/1876) remote: Counting objects: 5% (94/1876) remote: Counting objects: 6% (113/1876) remote: Counting objects: 7% (132/1876) remote: Counting objects: 8% (151/1876) remote: Counting objects: 9% (169/1876) remote: Counting objects: 10% (188/1876) remote: Counting objects: 11% (207/1876) remote: Counting objects: 12% (226/1876) remote: Counting objects: 13% (244/1876) remote: Counting objects: 14% (263/1876) remote: Counting objects: 15% (282/1876) remote: Counting objects: 16% (301/1876) remote: Counting objects: 17% (319/1876) remote: Counting objects: 18% (338/1876) remote: Counting objects: 19% (357/1876) remote: Counting objects: 20% (376/1876) remote: Counting objects: 21% (394/1876) remote: Counting objects: 22% (413/1876) remote: Counting objects: 23% (432/1876) remote: Counting objects: 24% (451/1876) remote: Counting objects: 25% (469/1876) remote: Counting objects: 26% (488/1876) remote: Counting objects: 27% (507/1876) remote: Counting objects: 28% (526/1876) remote: Counting objects: 29% (545/1876) remote: Counting objects: 30% (563/1876) remote: Counting objects: 31% (582/1876) remote: Counting objects: 32% (601/1876) remote: Counting objects: 33% (620/1876) remote: Counting objects: 34% (638/1876) remote: Counting objects: 35% (657/1876) remote: Counting objects: 36% (676/1876) remote: Counting objects: 37% (695/1876) remote: Counting objects: 38% (713/1876) remote: Counting objects: 39% (732/1876) remote: Counting objects: 40% (751/1876) remote: Counting objects: 41% (770/1876) remote: Counting objects: 42% (788/1876) remote: Counting objects: 43% (807/1876) remote: Counting objects: 44% (826/1876) remote: Counting objects: 45% (845/1876) remote: Counting objects: 46% (863/1876) remote: Counting objects: 47% (882/1876) remote: Counting objects: 48% (901/1876) remote: Counting objects: 49% (920/1876) remote: Counting objects: 50% (938/1876) remote: Counting objects: 51% (957/1876) remote: Counting objects: 52% (976/1876) remote: Counting objects: 53% (995/1876) remote: Counting objects: 54% (1014/1876) remote: Counting objects: 55% (1032/1876) remote: Counting objects: 56% (1051/1876) remote: Counting objects: 57% (1070/1876) remote: Counting objects: 58% (1089/1876) remote: Counting objects: 59% (1107/1876) remote: Counting objects: 60% (1126/1876) remote: Counting objects: 61% (1145/1876) remote: Counting objects: 62% (1164/1876) remote: Counting objects: 63% (1182/1876) remote: Counting objects: 64% (1201/1876) remote: Counting objects: 65% (1220/1876) remote: Counting objects: 66% (1239/1876) remote: Counting objects: 67% (1257/1876) remote: Counting objects: 68% (1276/1876) remote: Counting objects: 69% (1295/1876) remote: Counting objects: 70% (1314/1876) remote: Counting objects: 71% (1332/1876) remote: Counting objects: 72% (1351/1876) remote: Counting objects: 73% (1370/1876) remote: Counting objects: 74% (1389/1876) remote: Counting objects: 75% (1407/1876) remote: Counting objects: 76% (1426/1876) remote: Counting objects: 77% (1445/1876) remote: Counting objects: 78% (1464/1876) remote: Counting objects: 79% (1483/1876) remote: Counting objects: 80% (1501/1876) remote: Counting objects: 81% (1520/1876) remote: Counting objects: 82% (1539/1876) remote: Counting objects: 83% (1558/1876) remote: Counting objects: 84% (1576/1876) remote: Counting objects: 85% (1595/1876) remote: Counting objects: 86% (1614/1876) remote: Counting objects: 87% (1633/1876) remote: Counting objects: 88% (1651/1876) remote: Counting objects: 89% (1670/1876) remote: Counting objects: 90% (1689/1876) remote: Counting objects: 91% (1708/1876) remote: Counting objects: 92% (1726/1876) remote: Counting objects: 93% (1745/1876) remote: Counting objects: 94% (1764/1876) remote: Counting objects: 95% (1783/1876) remote: Counting objects: 96% (1801/1876) remote: Counting objects: 97% (1820/1876) remote: Counting objects: 98% (1839/1876) remote: CouLine truncated
remote: Compressing objects: 0% (1/1405) remote: Compressing objects: 1% (15/1405) remote: Compressing objects: 2% (29/1405) remote: Compressing objects: 3% (43/1405) remote: Compressing objects: 4% (57/1405) remote: Compressing objects: 5% (71/1405) remote: Compressing objects: 6% (85/1405) remote: Compressing objects: 7% (99/1405) remote: Compressing objects: 8% (113/1405) remote: Compressing objects: 9% (127/1405) remote: Compressing objects: 10% (141/1405) remote: Compressing objects: 11% (155/1405) remote: Compressing objects: 12% (169/1405) remote: Compressing objects: 13% (183/1405) remote: Compressing objects: 14% (197/1405) remote: Compressing objects: 15% (211/1405) remote: Compressing objects: 16% (225/1405) remote: Compressing objects: 17% (239/1405) remote: Compressing objects: 18% (253/1405) remote: Compressing objects: 19% (267/1405) remote: Compressing objects: 20% (281/1405) remote: Compressing objects: 21% (296/1405) remote: Compressing objects: 22% (310/1405) remote: Compressing objects: 23% (324/1405) remote: Compressing objects: 24% (338/1405) remote: Compressing objects: 25% (352/1405) remote: Compressing objects: 26% (366/1405) remote: Compressing objects: 27% (380/1405) remote: Compressing objects: 28% (394/1405) remote: Compressing objects: 29% (408/1405) remote: Compressing objects: 30% (422/1405) remote: Compressing objects: 31% (436/1405) remote: Compressing objects: 32% (450/1405) remote: Compressing objects: 33% (464/1405) remote: Compressing objects: 34% (478/1405) remote: Compressing objects: 35% (492/1405) remote: Compressing objects: 36% (506/1405) remote: Compressing objects: 37% (520/1405) remote: Compressing objects: 38% (534/1405) remote: Compressing objects: 39% (548/1405) remote: Compressing objects: 40% (562/1405) remote: Compressing objects: 41% (577/1405) remote: Compressing objects: 42% (591/1405) remote: Compressing objects: 43% (605/1405) remote: Compressing objects: 44% (619/1405) remote: Compressing objects: 45% (633/1405) remote: Compressing objects: 46% (647/1405) remote: Compressing objects: 47% (661/1405) remote: Compressing objects: 48% (675/1405) remote: Compressing objects: 49% (689/1405) remote: Compressing objects: 50% (703/1405) remote: Compressing objects: 51% (717/1405) remote: Compressing objects: 52% (731/1405) remote: Compressing objects: 53% (745/1405) remote: Compressing objects: 54% (759/1405) remote: Compressing objects: 55% (773/1405) remote: Compressing objects: 56% (787/1405) remote: Compressing objects: 57% (801/1405) remote: Compressing objects: 58% (815/1405) remote: Compressing objects: 59% (829/1405) remote: Compressing objects: 60% (843/1405) remote: Compressing objects: 61% (858/1405) remote: Compressing objects: 62% (872/1405) remote: Compressing objects: 63% (886/1405) remote: Compressing objects: 64% (900/1405) remote: Compressing objects: 65% (914/1405) remote: Compressing objects: 66% (928/1405) remote: Compressing objects: 67% (942/1405) remote: Compressing objects: 68% (956/1405) remote: Compressing objects: 69% (970/1405) remote: Compressing objects: 70% (984/1405) remote: Compressing objects: 71% (998/1405) remote: Compressing objects: 72% (1012/1405) remote: Compressing objects: 73% (1026/1405) remote: Compressing objects: 74% (1040/1405) remote: Compressing objects: 75% (1054/1405) remote: Compressing objects: 76% (1068/1405) remote: Compressing objects: 77% (1082/1405) remote: Compressing objects: 78% (1096/1405) remote: Compressing objects: 79% (1110/1405) remote: Compressing objects: 80% (1124/1405) remote: Compressing objects: 81% (1139/1405) remote: Compressing objects: 82% (1153/1405) remote: Compressing objects: 83% (1167/1405) remote: Compressing objects: 84% (1181/1405) remote: Compressing objects: 85% (1195/1405) remote: Compressing objects: 86% (1209/1405) remote: Compressing objects: 87% (1223/1405) remote: Compressing objects: 88% (1237/1405) remote: Compressing objects: 89% (1251/1405) remote: Compressing objects: 90% (1265/1405) remote: Compressing objects: 91% (1279/1405) remote: Compressing objects: 92% (1293/1405) remote: Compressing objects: 93% (1307/1405) remoLine truncated
Receiving objects: 0% (1/1876) Receiving objects: 1% (19/1876) Receiving objects: 2% (38/1876) Receiving objects: 3% (57/1876) Receiving objects: 4% (76/1876) Receiving objects: 5% (94/1876) Receiving objects: 6% (113/1876) Receiving objects: 7% (132/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 8% (151/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 9% (169/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 10% (188/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 11% (207/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 12% (226/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 13% (244/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 14% (263/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 15% (282/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 16% (301/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 17% (319/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 18% (338/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 19% (357/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 20% (376/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 21% (394/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 22% (413/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 23% (432/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 24% (451/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 25% (469/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 26% (488/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 27% (507/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 28% (526/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 29% (545/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 30% (563/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 31% (582/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 32% (601/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 33% (620/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 34% (638/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 35% (657/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 36% (676/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 37% (695/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 38% (713/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 39% (732/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 40% (751/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 41% (770/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 42% (788/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 43% (807/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 44% (826/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 45% (845/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 46% (863/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 47% (882/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 48% (901/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 49% (920/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 50% (938/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 51% (957/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 51% (965/1876), 10.20 MiB | 20.26 MiB/s Receiving objects: 52% (976/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 53% (995/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 54% (1014/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 55% (1032/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 56% (1051/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 57% (1070/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 58% (1089/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 59% (1107/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 60% (1126/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 61% (1145/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 62% (1164/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 63% (1182/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 64% (1201/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 65% (1220/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 66% (1239/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 67% (1257/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 68% (1276/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 69% (1295/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 70% (1314/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 71% (1332/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 72% (1351/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 73% (1370/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 74% (1389/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 75% (1407/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 76% (1426/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 77% (1445/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 78% (1464/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 79% (1483/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 80% (1501/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 81% (1520/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 82% (1539/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 83% (1558/1876), 35.39 MiB | 22.45 MiB/s Receiving objects: 84% (1576/1876), 35.39 MiB | 22Line truncated
Receiving objects: 100% (1876/1876), 35.39 MiB | 22.45 MiB/s␍Receiving objects: 100% (1876/1876), 47.76 MiB | 23.69 MiB/s, done.
Resolving deltas: 0% (0/320)␍Resolving deltas: 1% (4/320)␍Resolving deltas: 2% (7/320)␍Resolving deltas: 3% (10/320)␍Resolving deltas: 4% (13/320)␍Resolving deltas: 5% (16/320)␍Resolving deltas: 6% (20/320)␍Resolving deltas: 7% (23/320)␍Resolving deltas: 8% (26/320)␍Resolving deltas: 9% (29/320)␍Resolving deltas: 10% (32/320)␍Resolving deltas: 11% (36/320)␍Resolving deltas: 12% (39/320)␍Resolving deltas: 13% (42/320)␍Resolving deltas: 14% (45/320)␍Resolving deltas: 15% (48/320)␍Resolving deltas: 16% (52/320)␍Resolving deltas: 17% (55/320)␍Resolving deltas: 18% (58/320)␍Resolving deltas: 19% (61/320)␍Resolving deltas: 20% (64/320)␍Resolving deltas: 21% (68/320)␍Resolving deltas: 22% (71/320)␍Resolving deltas: 23% (74/320)␍Resolving deltas: 24% (77/320)␍Resolving deltas: 25% (80/320)␍Resolving deltas: 26% (85/320)␍Resolving deltas: 27% (87/320)␍Resolving deltas: 28% (90/320)␍Resolving deltas: 29% (93/320)␍Resolving deltas: 30% (96/320)␍Resolving deltas: 31% (100/320)␍Resolving deltas: 32% (103/320)␍Resolving deltas: 33% (106/320)␍Resolving deltas: 34% (110/320)␍Resolving deltas: 35% (112/320)␍Resolving deltas: 36% (116/320)␍Resolving deltas: 37% (119/320)␍Resolving deltas: 38% (122/320)␍Resolving deltas: 39% (125/320)␍Resolving deltas: 40% (128/320)␍Resolving deltas: 41% (132/320)␍Resolving deltas: 42% (135/320)␍Resolving deltas: 43% (138/320)␍Resolving deltas: 44% (142/320)␍Resolving deltas: 45% (144/320)␍Resolving deltas: 46% (148/320)␍Resolving deltas: 47% (151/320)␍Resolving deltas: 48% (154/320)␍Resolving deltas: 49% (157/320)␍Resolving deltas: 50% (160/320)␍Resolving deltas: 51% (164/320)␍Resolving deltas: 52% (167/320)␍Resolving deltas: 53% (170/320)␍Resolving deltas: 54% (173/320)␍Resolving deltas: 55% (176/320)␍Resolving deltas: 56% (180/320)␍Resolving deltas: 57% (183/320)␍Resolving deltas: 58% (186/320)␍Resolving deltas: 59% (189/320)␍Resolving deltas: 60% (192/320)␍Resolving deltas: 61% (196/320)␍Resolving deltas: 62% (199/320)␍Resolving deltas: 63% (202/320)␍Resolving deltas: 64% (205/320)␍Resolving deltas: 65% (208/320)␍Resolving deltas: 66% (212/320)␍Resolving deltas: 67% (215/320)␍Resolving deltas: 68% (218/320)␍Resolving deltas: 69% (221/320)␍Resolving deltas: 70% (224/320)␍Resolving deltas: 71% (228/320)␍Resolving deltas: 72% (231/320)␍Resolving deltas: 73% (234/320)␍Resolving deltas: 74% (237/320)␍Resolving deltas: 75% (240/320)␍Resolving deltas: 76% (244/320)␍Resolving deltas: 77% (247/320)␍Resolving deltas: 78% (250/320)␍Resolving deltas: 79% (253/320)␍Resolving deltas: 80% (256/320)␍Resolving deltas: 81% (260/320)␍Resolving deltas: 82% (263/320)␍Resolving deltas: 83% (266/320)␍Resolving deltas: 84% (269/320)␍Resolving deltas: 85% (272/320)␍Resolving deltas: 86% (276/320)␍Resolving deltas: 87% (279/320)␍Resolving deltas: 88% (282/320)␍Resolving deltas: 89% (285/320)␍Resolving deltas: 90% (288/320)␍Resolving deltas: 91% (292/320)␍Resolving deltas: 92% (295/320)␍Resolving deltas: 93% (298/320)␍Resolving deltas: 94% (301/320)␍Resolving deltas: 95% (304/320)␍Resolving deltas: 96% (308/320)␍Resolving deltas: 97% (311/320)␍Resolving deltas: 98% (314/320)␍Resolving deltas: 99% (317/320)␍Resolving deltas: 100% (320/320)␍Resolving deltas: 100% (320/320), done.
> Installing railpack, please wait…
____ _ _ _
| _ \ __ _(_) |_ __ __ _ ___| | __
| |_) / _` | | | '_ \ / _` |/ __| |/ /
| _ < (_| | | | |_) | (_| | (__| <
|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
|_|
Railpack is now installed!
Run 'railpack --help' to get started
railpack-dfm-aos-lgbcnc-t6ahqz
Preparing Railpack build plan...
╭─────────────────╮
│ Railpack 0.15.4 │
╰─────────────────╯
↳ Found .dockerignore file, applying filters
↳ Detected Node
↳ Using bun package manager
Packages
──────────
bun │ 1.4.4 │ railpack default (latest)
node │ 26.12.1 │ railpack default (latest)
Steps
──────────
▸ install
$ bun install --frozen-lockfile
▸ build
$ bun run build
Deploy
──────────
$ bun run start
✅ Railpack prepare completed.
Building with Railpack frontend...
#0 building with "railpack-dfm-aos-lgbcnc-t6ahqz" instance using docker-container driver
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 1.1s done
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-t6ahqz0
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-t6ahqz0 1.0s done
#1 DONE 2.1s
#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
#2 DONE 1.4s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 done
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.5s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.5s done
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 1.05MB / 3.86MB 0.6s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 2.10MB / 3.86MB 0.8s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.9s done
#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.1s done
#3 DONE 1.2s
#4 load build definition from railpack-plan.json
#4 transferring dockerfile: 5.06kB done
#4 DONE 0.0s
#5 loading .
#5 DONE 0.0s
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest 0.9s done
#7 DONE 0.9s
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 resolve ghcr.io/railwayapp/railpack-runtime:latest
#8 ...
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 DONE 1.0s
#5 loading .
#5 transferring context: 15.35MB 0.2s
#5 ...
#9 [railpack] loading secrets
#9 resolve docker.io/library/alpine:latest 1.6s done
#9 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.6s done
#9 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 0.3s done
#9 DONE 2.5s
#5 loading .
#5 ...
#10 [railpack] copy secrets hash
#10 DONE 0.7s
#5 loading .
#5 transferring context: 128.38MB 2.4s done
#5 DONE 2.8s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.2s done
#7 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.6s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 78.64MB / 237.08MB 2.6s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 41.94MB / 53.72MB 2.6s
#7 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.3s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 31.46MB / 67.81MB 2.1s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 1.5s done
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 5.24MB / 49.39MB 0.5s
#7 ...
#11 [railpack] hash used secrets
#11 DONE 0.5s
#12 [railpack] copy used secrets hash
#12 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 91.23MB / 237.08MB 2.9s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 11.53MB / 49.39MB 0.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 16.78MB / 49.39MB 0.8s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 37.75MB / 67.81MB 2.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 20.97MB / 49.39MB 0.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 112.20MB / 237.08MB 3.3s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 41.94MB / 67.81MB 2.7s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 49.28MB / 67.81MB 3.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 128.97MB / 237.08MB 3.8s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 27.26MB / 49.39MB 1.5s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 54.53MB / 67.81MB 3.3s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 31.46MB / 49.39MB 1.7s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 38.80MB / 49.39MB 1.8s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 60.82MB / 67.81MB 3.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 46.14MB / 49.39MB 2.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 150.99MB / 237.08MB 4.4s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.1s done
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 4.0s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 167.77MB / 237.08MB 4.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 181.40MB / 237.08MB 5.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 197.13MB / 237.08MB 5.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 209.72MB / 237.08MB 6.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 224.40MB / 237.08MB 6.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 7.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 7.4s done
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 44.04MB / 53.72MB 7.7s
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 4.3s done
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
#7 ...
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 resolve ghcr.io/railwayapp/railpack-runtime:latest 1.6s done
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 1.8s done
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.6s done
#8 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 2.6s done
#8 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.4s done
#8 DONE 10.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.4s done
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 46.14MB / 53.72MB 12.8s
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 2.9s done
#7 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
#7 ...
#13 install apt packages: libatomic1
#13 0.328 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
#13 0.416 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#13 0.439 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#13 0.516 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
#13 0.927 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
#13 0.930 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
#13 2.381 Fetched 10.2 MB in 2s (4712 kB/s)
#13 2.381 Reading package lists...
#13 3.392 Reading package lists...
#13 4.175 Building dependency tree...
#13 4.330 Reading state information...
#13 4.627 The following NEW packages will be installed:
#13 4.629 libatomic1
#13 4.743 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
#13 4.743 Need to get 9308 B of archives.
#13 4.743 After this operation, 46.1 kB of additional disk space will be used.
#13 4.743 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
#13 4.917 debconf: unable to initialize frontend: Dialog
#13 4.917 debconf: (TERM is not set, so the dialog frontend is not usable.)
#13 4.917 debconf: falling back to frontend: Readline
#13 4.917 debconf: unable to initialize frontend: Readline
#13 4.917 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
#13 4.917 debconf: falling back to frontend: Teletype
#13 4.922 debconf: unable to initialize frontend: Teletype
#13 4.922 debconf: (This frontend requires a controlling tty.)
#13 4.922 debconf: falling back to frontend: Noninteractive
#13 5.640 Fetched 9308 B in 0s (95.7 kB/s)
#13 5.670 Selecting previously unselected package libatomic1:amd64.
#13 5.670 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
#13 5.686 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
#13 5.692 Unpacking libatomic1:amd64 (14.2.0-19) ...
#13 5.730 Setting up libatomic1:amd64 (14.2.0-19) ...
#13 5.739 Processing triggers for libc-bin (2.41-12+deb13u4) ...
#13 DONE 6.4s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 48.23MB / 53.72MB 17.9s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 49.28MB / 53.72MB 23.0s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 51.38MB / 53.72MB 28.1s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 52.43MB / 53.72MB 33.2s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 34.6s done
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.0s done
#7 DONE 36.7s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 7.1s done
#7 DONE 43.7s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
#7 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
#7 DONE 43.8s
#14 mkdir /etc/mise
#14 DONE 0.4s
#15 create mise config
#15 DONE 0.0s
#16 install mise packages: bun, node
#16 0.083 mise by @jdx – installing 2 tools
#16 3.083 mise ███████░░░░░░░░░ 0/2 · 3.0s
#16 3.083 bun@1.4.4 downloading 2.7s 6.1/51.8 MB · 2.8 MB/s
#16 3.083 node@26.12.1 extracting 2.7s
#16 4.769 mise node@26.12.1 v26.12.1
#16 4.884 mise node@26.12.1 11.20.0
#16 4.916 mise ✓ node@26.12.1 4.5s node-v26.12.1-linux-x64.tar.gz
#16 6.083 mise ██████████░░░░░░ 1/2 · 6.0s
#16 6.083 bun@1.4.4 downloading 5.7s 25.2/51.8 MB · 4.9 MB/s
#16 8.951 mise bun@1.4.4 1.4.4
#16 8.963 mise ✓ bun@1.4.4 8.6s bun-linux-x64.zip
#16 8.963 mise ████████████████ 2/2 · installed 2 tools in 8.9s
#16 DONE 9.7s
#17 copy / /app
#17 ...
#18 copy /mise/shims
#18 DONE 0.0s
#17 copy / /app
#17 DONE 0.7s
#19 mkdir -p /app/node_modules/.cache
#19 DONE 0.1s
#20 bun install --frozen-lockfile
#20 0.115 bun install v1.4.4 (38afee6c8)
#20 ...
#21 copy /mise/installs
#21 DONE 6.6s
#20 bun install --frozen-lockfile
#20 ...
#22 copy /usr/local/bin/mise
#22 DONE 0.6s
#20 bun install --frozen-lockfile
#20 ...
#23 copy /etc/mise/config.toml
#23 DONE 0.0s
#24 copy /root/.local/state/mise
#24 DONE 0.0s
#20 bun install --frozen-lockfile
#20 16.44
#20 16.44 $ prisma generate || true
#20 19.49 Prisma schema loaded from prisma/schema.prisma
#20 20.50
#20 20.50 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 413ms
#20 20.50
#20 20.50 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#20 20.50
#20 20.50 Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate
#20 20.50
#20 20.62
#20 20.62 + @tailwindcss/postcss@4.1.18
#20 20.62 + @types/react@19.2.8
#20 20.62 + @types/react-dom@19.2.3
#20 20.62 + bun-types@1.3.6
#20 20.62 + eslint@9.39.2
#20 20.62 + eslint-config-next@16.1.3
#20 20.62 + tailwindcss@4.1.18
#20 20.62 + tw-animate-css@1.4.0
#20 20.62 + typescript@5.9.3
#20 20.62 + @dnd-kit/core@6.3.1
#20 20.62 + @dnd-kit/sortable@10.0.0
#20 20.62 + @dnd-kit/utilities@3.2.2
#20 20.62 + @hookform/resolvers@5.2.2
#20 20.62 + @hugeicons/core-free-icons@4.3.5
#20 20.62 + @hugeicons/react@1.1.10
#20 20.62 + @mdxeditor/editor@3.52.3
#20 20.62 + @prisma/client@6.19.2
#20 20.62 + @radix-ui/react-accordion@1.2.12
#20 20.62 + @radix-ui/react-alert-dialog@1.1.15
#20 20.62 + @radix-ui/react-aspect-ratio@1.1.8
#20 20.62 + @radix-ui/react-avatar@1.1.11
#20 20.62 + @radix-ui/react-checkbox@1.3.3
#20 20.62 + @radix-ui/react-collapsible@1.1.12
#20 20.62 + @radix-ui/react-context-menu@2.2.16
#20 20.62 + @radix-ui/react-dialog@1.1.15
#20 20.62 + @radix-ui/react-dropdown-menu@2.1.16
#20 20.62 + @radix-ui/react-hover-card@1.1.15
#20 20.62 + @radix-ui/react-label@2.1.8
#20 20.62 + @radix-ui/react-menubar@1.1.16
#20 20.62 + @radix-ui/react-navigation-menu@1.2.14
#20 20.62 + @radix-ui/react-popover@1.1.15
#20 20.62 + @radix-ui/react-progress@1.1.8
#20 20.62 + @radix-ui/react-radio-group@1.3.8
#20 20.62 + @radix-ui/react-scroll-area@1.2.10
#20 20.62 + @radix-ui/react-select@2.2.6
#20 20.62 + @radix-ui/react-separator@1.1.8
#20 20.62 + @radix-ui/react-slider@1.3.6
#20 20.62 + @radix-ui/react-slot@1.2.4
#20 20.62 + @radix-ui/react-switch@1.2.6
#20 20.62 + @radix-ui/react-tabs@1.1.13
#20 20.62 + @radix-ui/react-toast@1.2.15
#20 20.62 + @radix-ui/react-toggle@1.1.10
#20 20.62 + @radix-ui/react-toggle-group@1.1.11
#20 20.62 + @radix-ui/react-tooltip@1.2.8
#20 20.62 + @reactuses/core@6.1.9
#20 20.62 + @tanstack/react-query@5.90.19
#20 20.62 + @tanstack/react-table@8.21.3
#20 20.62 + class-variance-authority@0.7.1
#20 20.62 + clsx@2.1.1
#20 20.62 + cmdk@1.1.1
#20 20.62 + date-fns@4.1.0
#20 20.62 + embla-carousel-react@8.6.0
#20 20.62 + framer-motion@14.7.1
#20 20.62 + imapflow@2.9.1
#20 20.62 + input-otp@1.4.2
#20 20.62 + lucide-react@1.62.0
#20 20.62 + motion@12.43.0
#20 20.62 + next@16.1.3
#20 20.62 + next-auth@4.24.13
#20 20.62 + next-intl@4.7.0
#20 20.62 + next-themes@0.4.6
#20 20.62 + prisma@6.19.2
#20 20.62 + react@19.2.3
#20 20.62 + react-day-picker@9.13.0
#20 20.62 + react-dom@19.2.3
#20 20.62 + react-hook-form@7.71.1
#20 20.62 + react-markdown@10.1.0
#20 20.62 + react-resizable-panels@3.0.6
#20 20.62 + react-syntax-highlighter@15.6.6
#20 20.62 + recharts@2.15.4
#20 20.62 + sharp@0.34.5
#20 20.62 + sonner@2.0.7
#20 20.62 + tailwind-merge@3.7.0
#20 20.62 + tailwindcss-animate@1.0.7
#20 20.62 + uuid@11.1.0
#20 20.62 + vaul@1.1.2
#20 20.62 + z-ai-web-dev-sdk@0.0.18
#20 20.62 + zod@4.3.5
#20 20.62 + zustand@5.0.10
#20 20.62
#20 20.62 858 packages installed [20.50s]
#20 DONE 22.7s
#25 copy / /app
#25 DONE 5.8s
#26 bun run build
#26 0.191 $ prisma generate && next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
#26 1.454 Prisma schema loaded from prisma/schema.prisma
#26 2.440 ┌─────────────────────────────────────────────────────────┐
#26 2.440 │ Update available 6.19.2 -> 8.0.0-rc.28 │
#26 2.440 │ │
#26 2.440 │ This is a major update - please follow the guide at │
#26 2.440 │ https://pris.ly/d/major-version-upgrade │
#26 2.440 │ │
#26 2.440 │ Run the following to update │
#26 2.440 │ npm i --save-dev prisma@latest │
#26 2.440 │ npm i @prisma/client@latest │
#26 2.440 └─────────────────────────────────────────────────────────┘
#26 2.441
#26 2.441 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 598ms
#26 2.441
#26 2.441 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#26 2.441
#26 2.441 Tip: Interested in query caching in just a few lines of code? Try Accelerate today! https://pris.ly/tip-3-accelerate
#26 2.441
#26 2.805 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
#26 3.933 ▲ Next.js 16.1.3 (Turbopack)
#26 3.933
#26 3.977 Creating an optimized production build ...
#26 11.38 (node:109) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#26 11.38 (Use `node --trace-deprecation ...` to show where the warning was created)
#26 28.93
#26 28.93 > Build error occurred
#26 28.93 Error: Turbopack build failed with 2 errors:
#26 28.93 ./src/components/aos/fuse-cta.tsx:3:1
#26 28.93 Export default doesn't exist in target module
#26 28.93   1 | 'use client'
#26 28.93  2 |
#26 28.93 > 3 | import FuseButton from '@/components/FuseButton'
#26 28.93  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#26 28.93  4 | import { useState } from 'react'
#26 28.93  5 | import { toast } from 'sonner'
#26 28.93  6 | import { Loader2 } from 'lucide-react'
#26 28.93
#26 28.93 The export default was not found in module [project]/src/components/FuseButton.tsx [app-client] (ecmascript).
#26 28.93 Did you mean to import FuseButton?
#26 28.93 All exports of the module are statically known (It doesn't have dynamic exports). So it's known statically that the requested export doesn't exist.
#26 28.93
#26 28.93 Import traces:
#26 28.93 App Route:
#26 28.93 ./src/components/aos/fuse-cta.tsx
#26 28.93 ./src/lib/storage.ts
#26 28.93 ./src/app/api/aos/belege/upload/route.ts
#26 28.93
#26 28.93 Client Component Browser:
#26 28.93 ./src/components/aos/fuse-cta.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/views/recurring.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/app-shell.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/app-shell.tsx [Server Component]
#26 28.93 ./src/app/page.tsx [Server Component]
#26 28.93
#26 28.93 Client Component SSR:
#26 28.93 ./src/components/aos/fuse-cta.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/views/recurring.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/app-shell.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/app-shell.tsx [Server Component]
#26 28.93 ./src/app/page.tsx [Server Component]
#26 28.93
#26 28.93
#26 28.93 ./src/components/aos/fuse-cta.tsx:3:1
#26 28.93 Export default doesn't exist in target module
#26 28.93   1 | 'use client'
#26 28.93  2 |
#26 28.93 > 3 | import FuseButton from '@/components/FuseButton'
#26 28.93  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#26 28.93  4 | import { useState } from 'react'
#26 28.93  5 | import { toast } from 'sonner'
#26 28.93  6 | import { Loader2 } from 'lucide-react'
#26 28.93
#26 28.93 The export default was not found in module [project]/src/components/FuseButton.tsx [app-ssr] (ecmascript).
#26 28.93 Did you mean to import FuseButton?
#26 28.93 All exports of the module are statically known (It doesn't have dynamic exports). So it's known statically that the requested export doesn't exist.
#26 28.93
#26 28.93 Import traces:
#26 28.93 App Route:
#26 28.93 ./src/components/aos/fuse-cta.tsx
#26 28.93 ./src/lib/storage.ts
#26 28.93 ./src/app/api/aos/belege/upload/route.ts
#26 28.93
#26 28.93 Client Component Browser:
#26 28.93 ./src/components/aos/fuse-cta.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/views/recurring.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/app-shell.tsx [Client Component Browser]
#26 28.93 ./src/components/aos/app-shell.tsx [Server Component]
#26 28.93 ./src/app/page.tsx [Server Component]
#26 28.93
#26 28.93 Client Component SSR:
#26 28.93 ./src/components/aos/fuse-cta.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/views/recurring.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/app-shell.tsx [Client Component SSR]
#26 28.93 ./src/components/aos/app-shell.tsx [Server Component]
#26 28.93 ./src/app/page.tsx [Server Component]
#26 28.93
#26 28.93
#26 28.93 at <unknown> (./src/components/aos/fuse-cta.tsx:3:1)
#26 28.93 at <unknown> (./src/components/aos/fuse-cta.tsx:3:1)
#26 29.12 error: script "build" exited with code 1
#26 ERROR: process "bun run build" did not complete successfully: exit code: 1
------
> bun run build:
28.93 ./src/components/aos/fuse-cta.tsx [Client Component SSR]
28.93 ./src/components/aos/views/recurring.tsx [Client Component SSR]
28.93 ./src/components/aos/app-shell.tsx [Client Component SSR]
28.93 ./src/components/aos/app-shell.tsx [Server Component]
28.93 ./src/app/page.tsx [Server Component]
28.93
28.93
28.93 at <unknown> (./src/components/aos/fuse-cta.tsx:3:1)
28.93 at <unknown> (./src/components/aos/fuse-cta.tsx:3:1)
29.12 error: script "build" exited with code 1
------
ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
❌ Railpack build failed
railpack-dfm-aos-lgbcnc-t6ahqz removed
Error occurred ❌, check the logs for details.
-483
View File
@@ -1,483 +0,0 @@
Initializing deployment
Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
remote: Enumerating objects: 1876, done.
remote: Counting objects: 0% (1/1876) remote: Counting objects: 1% (19/1876) remote: Counting objects: 2% (38/1876) remote: Counting objects: 3% (57/1876) remote: Counting objects: 4% (76/1876) remote: Counting objects: 5% (94/1876) remote: Counting objects: 6% (113/1876) remote: Counting objects: 7% (132/1876) remote: Counting objects: 8% (151/1876) remote: Counting objects: 9% (169/1876) remote: Counting objects: 10% (188/1876) remote: Counting objects: 11% (207/1876) remote: Counting objects: 12% (226/1876) remote: Counting objects: 13% (244/1876) remote: Counting objects: 14% (263/1876) remote: Counting objects: 15% (282/1876) remote: Counting objects: 16% (301/1876) remote: Counting objects: 17% (319/1876) remote: Counting objects: 18% (338/1876) remote: Counting objects: 19% (357/1876) remote: Counting objects: 20% (376/1876) remote: Counting objects: 21% (394/1876) remote: Counting objects: 22% (413/1876) remote: Counting objects: 23% (432/1876) remote: Counting objects: 24% (451/1876) remote: Counting objects: 25% (469/1876) remote: Counting objects: 26% (488/1876) remote: Counting objects: 27% (507/1876) remote: Counting objects: 28% (526/1876) remote: Counting objects: 29% (545/1876) remote: Counting objects: 30% (563/1876) remote: Counting objects: 31% (582/1876) remote: Counting objects: 32% (601/1876) remote: Counting objects: 33% (620/1876) remote: Counting objects: 34% (638/1876) remote: Counting objects: 35% (657/1876) remote: Counting objects: 36% (676/1876) remote: Counting objects: 37% (695/1876) remote: Counting objects: 38% (713/1876) remote: Counting objects: 39% (732/1876) remote: Counting objects: 40% (751/1876) remote: Counting objects: 41% (770/1876) remote: Counting objects: 42% (788/1876) remote: Counting objects: 43% (807/1876) remote: Counting objects: 44% (826/1876) remote: Counting objects: 45% (845/1876) remote: Counting objects: 46% (863/1876) remote: Counting objects: 47% (882/1876) remote: Counting objects: 48% (901/1876) remote: Counting objects: 49% (920/1876) remote: Counting objects: 50% (938/1876) remote: Counting objects: 51% (957/1876) remote: Counting objects: 52% (976/1876) remote: Counting objects: 53% (995/1876) remote: Counting objects: 54% (1014/1876) remote: Counting objects: 55% (1032/1876) remote: Counting objects: 56% (1051/1876) remote: Counting objects: 57% (1070/1876) remote: Counting objects: 58% (1089/1876) remote: Counting objects: 59% (1107/1876) remote: Counting objects: 60% (1126/1876) remote: Counting objects: 61% (1145/1876) remote: Counting objects: 62% (1164/1876) remote: Counting objects: 63% (1182/1876) remote: Counting objects: 64% (1201/1876) remote: Counting objects: 65% (1220/1876) remote: Counting objects: 66% (1239/1876) remote: Counting objects: 67% (1257/1876) remote: Counting objects: 68% (1276/1876) remote: Counting objects: 69% (1295/1876) remote: Counting objects: 70% (1314/1876) remote: Counting objects: 71% (1332/1876) remote: Counting objects: 72% (1351/1876) remote: Counting objects: 73% (1370/1876) remote: Counting objects: 74% (1389/1876) remote: Counting objects: 75% (1407/1876) remote: Counting objects: 76% (1426/1876) remote: Counting objects: 77% (1445/1876) remote: Counting objects: 78% (1464/1876) remote: Counting objects: 79% (1483/1876) remote: Counting objects: 80% (1501/1876) remote: Counting objects: 81% (1520/1876) remote: Counting objects: 82% (1539/1876) remote: Counting objects: 83% (1558/1876) remote: Counting objects: 84% (1576/1876) remote: Counting objects: 85% (1595/1876) remote: Counting objects: 86% (1614/1876) remote: Counting objects: 87% (1633/1876) remote: Counting objects: 88% (1651/1876) remote: Counting objects: 89% (1670/1876) remote: Counting objects: 90% (1689/1876) remote: Counting objects: 91% (1708/1876) remote: Counting objects: 92% (1726/1876) remote: Counting objects: 93% (1745/1876) remote: Counting objects: 94% (1764/1876) remote: Counting objects: 95% (1783/1876) remote: Counting objects: 96% (1801/1876) remote: Counting objects: 97% (1820/1876) remote: Counting objects: 98% (1839/1876) remote: CouLine truncated
remote: Compressing objects: 0% (1/1405) remote: Compressing objects: 1% (15/1405) remote: Compressing objects: 2% (29/1405) remote: Compressing objects: 3% (43/1405) remote: Compressing objects: 4% (57/1405) remote: Compressing objects: 5% (71/1405) remote: Compressing objects: 6% (85/1405) remote: Compressing objects: 7% (99/1405) remote: Compressing objects: 8% (113/1405) remote: Compressing objects: 9% (127/1405) remote: Compressing objects: 10% (141/1405) remote: Compressing objects: 11% (155/1405) remote: Compressing objects: 12% (169/1405) remote: Compressing objects: 13% (183/1405) remote: Compressing objects: 14% (197/1405) remote: Compressing objects: 15% (211/1405) remote: Compressing objects: 16% (225/1405) remote: Compressing objects: 17% (239/1405) remote: Compressing objects: 18% (253/1405) remote: Compressing objects: 19% (267/1405) remote: Compressing objects: 20% (281/1405) remote: Compressing objects: 21% (296/1405) remote: Compressing objects: 22% (310/1405) remote: Compressing objects: 23% (324/1405) remote: Compressing objects: 24% (338/1405) remote: Compressing objects: 25% (352/1405) remote: Compressing objects: 26% (366/1405) remote: Compressing objects: 27% (380/1405) remote: Compressing objects: 28% (394/1405) remote: Compressing objects: 29% (408/1405) remote: Compressing objects: 30% (422/1405) remote: Compressing objects: 31% (436/1405) remote: Compressing objects: 32% (450/1405) remote: Compressing objects: 33% (464/1405) remote: Compressing objects: 34% (478/1405) remote: Compressing objects: 35% (492/1405) remote: Compressing objects: 36% (506/1405) remote: Compressing objects: 37% (520/1405) remote: Compressing objects: 38% (534/1405) remote: Compressing objects: 39% (548/1405) remote: Compressing objects: 40% (562/1405) remote: Compressing objects: 41% (577/1405) remote: Compressing objects: 42% (591/1405) remote: Compressing objects: 43% (605/1405) remote: Compressing objects: 44% (619/1405) remote: Compressing objects: 45% (633/1405) remote: Compressing objects: 46% (647/1405) remote: Compressing objects: 47% (661/1405) remote: Compressing objects: 48% (675/1405) remote: Compressing objects: 49% (689/1405) remote: Compressing objects: 50% (703/1405) remote: Compressing objects: 51% (717/1405) remote: Compressing objects: 52% (731/1405) remote: Compressing objects: 53% (745/1405) remote: Compressing objects: 54% (759/1405) remote: Compressing objects: 55% (773/1405) remote: Compressing objects: 56% (787/1405) remote: Compressing objects: 57% (801/1405) remote: Compressing objects: 58% (815/1405) remote: Compressing objects: 59% (829/1405) remote: Compressing objects: 60% (843/1405) remote: Compressing objects: 61% (858/1405) remote: Compressing objects: 62% (872/1405) remote: Compressing objects: 63% (886/1405) remote: Compressing objects: 64% (900/1405) remote: Compressing objects: 65% (914/1405) remote: Compressing objects: 66% (928/1405) remote: Compressing objects: 67% (942/1405) remote: Compressing objects: 68% (956/1405) remote: Compressing objects: 69% (970/1405) remote: Compressing objects: 70% (984/1405) remote: Compressing objects: 71% (998/1405) remote: Compressing objects: 72% (1012/1405) remote: Compressing objects: 73% (1026/1405) remote: Compressing objects: 74% (1040/1405) remote: Compressing objects: 75% (1054/1405) remote: Compressing objects: 76% (1068/1405) remote: Compressing objects: 77% (1082/1405) remote: Compressing objects: 78% (1096/1405) remote: Compressing objects: 79% (1110/1405) remote: Compressing objects: 80% (1124/1405) remote: Compressing objects: 81% (1139/1405) remote: Compressing objects: 82% (1153/1405) remote: Compressing objects: 83% (1167/1405) remote: Compressing objects: 84% (1181/1405) remote: Compressing objects: 85% (1195/1405) remote: Compressing objects: 86% (1209/1405) remote: Compressing objects: 87% (1223/1405) remote: Compressing objects: 88% (1237/1405) remote: Compressing objects: 89% (1251/1405) remote: Compressing objects: 90% (1265/1405) remote: Compressing objects: 91% (1279/1405) remote: Compressing objects: 92% (1293/1405) remote: Compressing objects: 93% (1307/1405) remoLine truncated
Receiving objects: 0% (1/1876) Receiving objects: 1% (19/1876) Receiving objects: 2% (38/1876) Receiving objects: 3% (57/1876) Receiving objects: 4% (76/1876) Receiving objects: 5% (94/1876) Receiving objects: 6% (113/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 7% (132/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 8% (151/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 9% (169/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 10% (188/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 11% (207/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 12% (226/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 13% (244/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 14% (263/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 15% (282/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 16% (301/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 17% (319/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 18% (338/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 19% (357/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 20% (376/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 21% (394/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 22% (413/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 23% (432/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 24% (451/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 25% (469/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 26% (488/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 27% (507/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 28% (526/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 29% (545/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 30% (563/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 31% (582/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 32% (601/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 33% (620/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 34% (638/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 35% (657/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 36% (676/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 37% (695/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 38% (713/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 39% (732/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 40% (751/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 41% (770/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 42% (788/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 43% (807/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 44% (826/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 45% (845/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 46% (863/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 47% (882/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 48% (901/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 49% (920/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 50% (938/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 51% (957/1876), 9.43 MiB | 18.84 MiB/s Receiving objects: 51% (974/1876), 26.50 MiB | 26.42 MiB/s Receiving objects: 52% (976/1876), 26.50 MiB | 26.42 MiB/s Receiving objects: 53% (995/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 54% (1014/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 55% (1032/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 56% (1051/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 57% (1070/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 58% (1089/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 59% (1107/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 60% (1126/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 61% (1145/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 62% (1164/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 63% (1182/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 64% (1201/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 65% (1220/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 66% (1239/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 67% (1257/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 68% (1276/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 69% (1295/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 70% (1314/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 71% (1332/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 72% (1351/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 73% (1370/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 74% (1389/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 75% (1407/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 76% (1426/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 77% (1445/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 78% (1464/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 79% (1483/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 80% (1501/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 81% (1520/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 82% (1539/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 83% (1558/1876), 41.91 MiB | 27.88 MiB/s Receiving objects: 84% (1576/1876), 41.91 MiB | 27.88 MiB/s Receiving oLine truncated
Receiving objects: 100% (1876/1876), 41.91 MiB | 27.88 MiB/s␍Receiving objects: 100% (1876/1876), 47.76 MiB | 27.79 MiB/s, done.
Resolving deltas: 0% (0/320)␍Resolving deltas: 1% (4/320)␍Resolving deltas: 2% (7/320)␍Resolving deltas: 3% (10/320)␍Resolving deltas: 4% (13/320)␍Resolving deltas: 5% (16/320)␍Resolving deltas: 6% (20/320)␍Resolving deltas: 7% (23/320)␍Resolving deltas: 8% (26/320)␍Resolving deltas: 9% (29/320)␍Resolving deltas: 10% (32/320)␍Resolving deltas: 11% (36/320)␍Resolving deltas: 12% (39/320)␍Resolving deltas: 13% (42/320)␍Resolving deltas: 14% (45/320)␍Resolving deltas: 15% (48/320)␍Resolving deltas: 16% (52/320)␍Resolving deltas: 17% (55/320)␍Resolving deltas: 18% (58/320)␍Resolving deltas: 19% (61/320)␍Resolving deltas: 20% (64/320)␍Resolving deltas: 21% (68/320)␍Resolving deltas: 22% (71/320)␍Resolving deltas: 23% (74/320)␍Resolving deltas: 24% (77/320)␍Resolving deltas: 25% (80/320)␍Resolving deltas: 26% (84/320)␍Resolving deltas: 27% (87/320)␍Resolving deltas: 28% (90/320)␍Resolving deltas: 29% (93/320)␍Resolving deltas: 30% (96/320)␍Resolving deltas: 31% (100/320)␍Resolving deltas: 32% (103/320)␍Resolving deltas: 33% (106/320)␍Resolving deltas: 34% (109/320)␍Resolving deltas: 35% (112/320)␍Resolving deltas: 36% (116/320)␍Resolving deltas: 37% (119/320)␍Resolving deltas: 38% (122/320)␍Resolving deltas: 39% (125/320)␍Resolving deltas: 40% (128/320)␍Resolving deltas: 41% (132/320)␍Resolving deltas: 42% (135/320)␍Resolving deltas: 43% (138/320)␍Resolving deltas: 44% (141/320)␍Resolving deltas: 45% (144/320)␍Resolving deltas: 46% (149/320)␍Resolving deltas: 47% (151/320)␍Resolving deltas: 48% (154/320)␍Resolving deltas: 49% (158/320)␍Resolving deltas: 50% (160/320)␍Resolving deltas: 51% (164/320)␍Resolving deltas: 52% (167/320)␍Resolving deltas: 53% (170/320)␍Resolving deltas: 54% (173/320)␍Resolving deltas: 55% (176/320)␍Resolving deltas: 56% (180/320)␍Resolving deltas: 57% (183/320)␍Resolving deltas: 58% (187/320)␍Resolving deltas: 59% (189/320)␍Resolving deltas: 60% (192/320)␍Resolving deltas: 61% (196/320)␍Resolving deltas: 62% (199/320)␍Resolving deltas: 63% (202/320)␍Resolving deltas: 64% (206/320)␍Resolving deltas: 65% (208/320)␍Resolving deltas: 66% (212/320)␍Resolving deltas: 67% (215/320)␍Resolving deltas: 68% (218/320)␍Resolving deltas: 69% (221/320)␍Resolving deltas: 70% (224/320)␍Resolving deltas: 71% (229/320)␍Resolving deltas: 72% (231/320)␍Resolving deltas: 73% (234/320)␍Resolving deltas: 74% (237/320)␍Resolving deltas: 75% (241/320)␍Resolving deltas: 76% (244/320)␍Resolving deltas: 77% (247/320)␍Resolving deltas: 78% (250/320)␍Resolving deltas: 79% (253/320)␍Resolving deltas: 80% (256/320)␍Resolving deltas: 81% (260/320)␍Resolving deltas: 82% (263/320)␍Resolving deltas: 83% (266/320)␍Resolving deltas: 84% (269/320)␍Resolving deltas: 85% (272/320)␍Resolving deltas: 86% (276/320)␍Resolving deltas: 87% (279/320)␍Resolving deltas: 88% (282/320)␍Resolving deltas: 89% (285/320)␍Resolving deltas: 90% (288/320)␍Resolving deltas: 91% (292/320)␍Resolving deltas: 92% (295/320)␍Resolving deltas: 93% (298/320)␍Resolving deltas: 94% (302/320)␍Resolving deltas: 95% (304/320)␍Resolving deltas: 96% (308/320)␍Resolving deltas: 97% (311/320)␍Resolving deltas: 98% (314/320)␍Resolving deltas: 99% (317/320)␍Resolving deltas: 100% (320/320)␍Resolving deltas: 100% (320/320), done.
> Installing railpack, please wait…
____ _ _ _
| _ \ __ _(_) |_ __ __ _ ___| | __
| |_) / _` | | | '_ \ / _` |/ __| |/ /
| _ < (_| | | | |_) | (_| | (__| <
|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
|_|
Railpack is now installed!
Run 'railpack --help' to get started
railpack-dfm-aos-lgbcnc-fk4Q2Q
Preparing Railpack build plan...
╭─────────────────╮
│ Railpack 0.15.4 │
╰─────────────────╯
↳ Found .dockerignore file, applying filters
↳ Detected Node
↳ Using bun package manager
Packages
──────────
bun │ 1.4.4 │ railpack default (latest)
node │ 26.12.1 │ railpack default (latest)
Steps
──────────
▸ install
$ bun install --frozen-lockfile
▸ build
$ bun run build
Deploy
──────────
$ bun run start
✅ Railpack prepare completed.
Building with Railpack frontend...
#0 building with "railpack-dfm-aos-lgbcnc-fk4Q2Q" instance using docker-container driver
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 1.1s done
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-fk4q2q0
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-fk4q2q0 0.8s done
#1 DONE 1.9s
#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
#2 DONE 1.3s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 0.0s done
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.5s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.5s done
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.7s done
#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
#3 DONE 0.9s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.2s done
#3 DONE 1.1s
#4 load build definition from railpack-plan.json
#4 transferring dockerfile: 5.06kB done
#4 DONE 0.0s
#5 [railpack] secrets hash
#5 DONE 0.0s
#6 loading .
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest 1.0s done
#7 DONE 1.0s
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 resolve ghcr.io/railwayapp/railpack-runtime:latest
#8 ...
#5 [railpack] secrets hash
#5 DONE 0.0s
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 resolve ghcr.io/railwayapp/railpack-runtime:latest 1.1s done
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0B / 7.39MB 0.2s
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 0B / 29.84MB 0.2s
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 4.19MB / 29.84MB 0.3s
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 1.05MB / 7.39MB 0.5s
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 10.49MB / 29.84MB 0.5s
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 3.15MB / 7.39MB 0.6s
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 13.63MB / 29.84MB 0.6s
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.8s
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.8s done
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 18.87MB / 29.84MB 0.8s
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 20.97MB / 29.84MB 0.9s
#8 ...
#9 [railpack] loading secrets
#9 resolve docker.io/library/alpine:latest 1.4s done
#9 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.4s done
#9 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 0.3s done
#9 DONE 2.2s
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 1.1s
#8 ...
#10 [railpack] copy secrets hash
#10 DONE 0.3s
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 1.3s done
#8 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e
#8 ...
#11 [railpack] hash used secrets
#11 DONE 0.4s
#12 [railpack] copy used secrets hash
#12 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.5s done
#7 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.5s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 6.29MB / 237.08MB 1.4s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 41.94MB / 53.72MB 1.4s
#7 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.2s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 28.51MB / 67.81MB 1.1s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.05MB / 25.64MB 0.6s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 45.63MB / 53.72MB 1.5s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 32.51MB / 67.81MB 1.2s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 52.43MB / 53.72MB 1.7s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 4.19MB / 25.64MB 0.9s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 1.8s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 41.94MB / 67.81MB 1.4s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 47.19MB / 67.81MB 1.5s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 7.34MB / 25.64MB 1.2s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 52.43MB / 67.81MB 1.7s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 0B / 49.39MB 0.2s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 57.67MB / 67.81MB 1.8s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 9.44MB / 25.64MB 1.4s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 11.53MB / 25.64MB 1.5s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 8.39MB / 49.39MB 0.5s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 65.01MB / 67.81MB 2.1s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 14.68MB / 25.64MB 1.7s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 16.78MB / 49.39MB 0.6s
#7 ...
#6 loading .
#6 transferring context: 128.38MB 3.2s done
#6 DONE 3.3s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 17.83MB / 25.64MB 1.8s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 23.07MB / 49.39MB 0.8s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 2.4s done
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 22.02MB / 25.64MB 2.0s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 27.26MB / 49.39MB 0.9s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 2.1s done
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 34.60MB / 49.39MB 1.1s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 41.94MB / 49.39MB 1.2s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 46.14MB / 49.39MB 1.4s
#7 ...
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 2.3s done
#8 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.3s done
#8 DONE 5.1s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 1.5s done
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 1.5s done
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.0s done
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 8.39MB / 237.08MB 6.5s
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 2.6s done
#7 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.3s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 9.44MB / 237.08MB 11.6s
#7 ...
#13 install apt packages: libatomic1
#13 0.202 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
#13 0.277 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#13 0.304 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#13 0.332 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
#13 0.502 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
#13 0.530 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
#13 1.907 Fetched 10.2 MB in 2s (5691 kB/s)
#13 1.907 Reading package lists...
#13 2.959 Reading package lists...
#13 4.052 Building dependency tree...
#13 4.297 Reading state information...
#13 4.774 The following NEW packages will be installed:
#13 4.776 libatomic1
#13 4.901 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
#13 4.901 Need to get 9308 B of archives.
#13 4.901 After this operation, 46.1 kB of additional disk space will be used.
#13 4.901 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
#13 5.095 debconf: unable to initialize frontend: Dialog
#13 5.095 debconf: (TERM is not set, so the dialog frontend is not usable.)
#13 5.095 debconf: falling back to frontend: Readline
#13 5.095 debconf: unable to initialize frontend: Readline
#13 5.095 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
#13 5.095 debconf: falling back to frontend: Teletype
#13 5.101 debconf: unable to initialize frontend: Teletype
#13 5.101 debconf: (This frontend requires a controlling tty.)
#13 5.101 debconf: falling back to frontend: Noninteractive
#13 6.113 Fetched 9308 B in 0s (91.1 kB/s)
#13 6.163 Selecting previously unselected package libatomic1:amd64.
#13 6.163 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
#13 6.171 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
#13 6.174 Unpacking libatomic1:amd64 (14.2.0-19) ...
#13 6.211 Setting up libatomic1:amd64 (14.2.0-19) ...
#13 6.217 Processing triggers for libc-bin (2.41-12+deb13u4) ...
#13 DONE 8.2s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 28.31MB / 237.08MB 16.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 41.94MB / 237.08MB 16.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 55.57MB / 237.08MB 17.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 65.01MB / 237.08MB 22.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 66.06MB / 237.08MB 27.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 68.16MB / 237.08MB 32.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 69.21MB / 237.08MB 37.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 71.30MB / 237.08MB 42.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 72.35MB / 237.08MB 47.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 85.98MB / 237.08MB 50.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 94.37MB / 237.08MB 55.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 96.47MB / 237.08MB 60.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 97.52MB / 237.08MB 65.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 99.61MB / 237.08MB 70.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 100.66MB / 237.08MB 75.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 101.71MB / 237.08MB 81.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 103.81MB / 237.08MB 86.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 124.78MB / 237.08MB 87.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 137.36MB / 237.08MB 90.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 137.36MB / 237.08MB 95.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 139.46MB / 237.08MB 100.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 140.51MB / 237.08MB 105.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 141.56MB / 237.08MB 111.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 143.65MB / 237.08MB 116.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 145.75MB / 237.08MB 121.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 162.53MB / 237.08MB 122.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 168.82MB / 237.08MB 127.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 169.87MB / 237.08MB 132.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 170.92MB / 237.08MB 138.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 171.97MB / 237.08MB 143.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 174.06MB / 237.08MB 148.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 175.11MB / 237.08MB 153.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 176.16MB / 237.08MB 158.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 177.21MB / 237.08MB 163.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 189.79MB / 237.08MB 164.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 200.28MB / 237.08MB 169.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 202.38MB / 237.08MB 174.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 203.42MB / 237.08MB 179.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 205.52MB / 237.08MB 184.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 207.62MB / 237.08MB 189.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 208.67MB / 237.08MB 194.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 216.01MB / 237.08MB 200.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 219.15MB / 237.08MB 205.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 231.74MB / 237.08MB 207.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 207.6s done
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 6.2s done
#7 DONE 215.5s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
#7 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
#7 DONE 215.5s
#14 mkdir /etc/mise
#14 DONE 1.7s
#15 create mise config
#15 DONE 0.0s
#16 install mise packages: bun, node
#16 0.083 mise by @jdx – installing 2 tools
#16 3.083 mise ████████░░░░░░░░ 0/2 · 3.0s
#16 3.083 bun@1.4.4 downloading 2.7s 28.2/51.8 MB · 11.6 MB/s
#16 3.083 node@26.12.1 downloading 2.7s 62.9/62.9 MB · 24.6 MB/s
#16 4.964 mise node@26.12.1 v26.12.1
#16 5.189 mise node@26.12.1 11.20.0
#16 5.226 mise ✓ node@26.12.1 4.8s node-v26.12.1-linux-x64.tar.gz
#16 6.083 mise ██████████████░░ 1/2 · 6.0s
#16 6.083 bun@1.4.4 extracting 5.7s
#16 6.724 mise bun@1.4.4 1.4.4
#16 6.751 mise ✓ bun@1.4.4 6.4s bun-linux-x64.zip
#16 6.751 mise ████████████████ 2/2 · installed 2 tools in 6.7s
#16 DONE 7.5s
#17 copy / /app
#17 DONE 0.6s
#18 mkdir -p /app/node_modules/.cache
#18 DONE 0.2s
#19 copy /mise/shims
#19 DONE 0.0s
#20 bun install --frozen-lockfile
#20 0.118 bun install v1.4.4 (38afee6c8)
#20 11.51
#20 11.52 $ prisma generate || true
#20 ...
#21 copy /mise/installs
#21 DONE 10.0s
#22 copy /usr/local/bin/mise
#22 DONE 0.9s
#20 bun install --frozen-lockfile
#20 ...
#23 copy /etc/mise/config.toml
#23 DONE 0.0s
#24 copy /root/.local/state/mise
#24 DONE 0.0s
#20 bun install --frozen-lockfile
#20 14.20 Prisma schema loaded from prisma/schema.prisma
#20 15.86
#20 15.86 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 703ms
#20 15.86
#20 15.86 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#20 15.86
#20 15.86 Tip: Interested in query caching in just a few lines of code? Try Accelerate today! https://pris.ly/tip-3-accelerate
#20 15.86
#20 16.19
#20 16.19 + @tailwindcss/postcss@4.1.18
#20 16.19 + @types/react@19.2.8
#20 16.19 + @types/react-dom@19.2.3
#20 16.19 + bun-types@1.3.6
#20 16.19 + eslint@9.39.2
#20 16.19 + eslint-config-next@16.1.3
#20 16.19 + tailwindcss@4.1.18
#20 16.19 + tw-animate-css@1.4.0
#20 16.19 + typescript@5.9.3
#20 16.19 + @dnd-kit/core@6.3.1
#20 16.19 + @dnd-kit/sortable@10.0.0
#20 16.19 + @dnd-kit/utilities@3.2.2
#20 16.19 + @hookform/resolvers@5.2.2
#20 16.19 + @hugeicons/core-free-icons@4.3.5
#20 16.19 + @hugeicons/react@1.1.10
#20 16.19 + @mdxeditor/editor@3.52.3
#20 16.19 + @prisma/client@6.19.2
#20 16.19 + @radix-ui/react-accordion@1.2.12
#20 16.19 + @radix-ui/react-alert-dialog@1.1.15
#20 16.19 + @radix-ui/react-aspect-ratio@1.1.8
#20 16.19 + @radix-ui/react-avatar@1.1.11
#20 16.19 + @radix-ui/react-checkbox@1.3.3
#20 16.19 + @radix-ui/react-collapsible@1.1.12
#20 16.19 + @radix-ui/react-context-menu@2.2.16
#20 16.19 + @radix-ui/react-dialog@1.1.15
#20 16.19 + @radix-ui/react-dropdown-menu@2.1.16
#20 16.19 + @radix-ui/react-hover-card@1.1.15
#20 16.19 + @radix-ui/react-label@2.1.8
#20 16.19 + @radix-ui/react-menubar@1.1.16
#20 16.19 + @radix-ui/react-navigation-menu@1.2.14
#20 16.19 + @radix-ui/react-popover@1.1.15
#20 16.19 + @radix-ui/react-progress@1.1.8
#20 16.19 + @radix-ui/react-radio-group@1.3.8
#20 16.19 + @radix-ui/react-scroll-area@1.2.10
#20 16.19 + @radix-ui/react-select@2.2.6
#20 16.19 + @radix-ui/react-separator@1.1.8
#20 16.19 + @radix-ui/react-slider@1.3.6
#20 16.19 + @radix-ui/react-slot@1.2.4
#20 16.19 + @radix-ui/react-switch@1.2.6
#20 16.19 + @radix-ui/react-tabs@1.1.13
#20 16.19 + @radix-ui/react-toast@1.2.15
#20 16.19 + @radix-ui/react-toggle@1.1.10
#20 16.19 + @radix-ui/react-toggle-group@1.1.11
#20 16.19 + @radix-ui/react-tooltip@1.2.8
#20 16.19 + @reactuses/core@6.1.9
#20 16.19 + @tanstack/react-query@5.90.19
#20 16.19 + @tanstack/react-table@8.21.3
#20 16.19 + class-variance-authority@0.7.1
#20 16.19 + clsx@2.1.1
#20 16.19 + cmdk@1.1.1
#20 16.19 + date-fns@4.1.0
#20 16.19 + embla-carousel-react@8.6.0
#20 16.19 + framer-motion@14.7.1
#20 16.19 + imapflow@2.9.1
#20 16.19 + input-otp@1.4.2
#20 16.19 + lucide-react@1.62.0
#20 16.19 + motion@12.43.0
#20 16.19 + next@16.1.3
#20 16.19 + next-auth@4.24.13
#20 16.19 + next-intl@4.7.0
#20 16.19 + next-themes@0.4.6
#20 16.19 + prisma@6.19.2
#20 16.19 + react@19.2.3
#20 16.19 + react-day-picker@9.13.0
#20 16.19 + react-dom@19.2.3
#20 16.19 + react-hook-form@7.71.1
#20 16.19 + react-markdown@10.1.0
#20 16.19 + react-resizable-panels@3.0.6
#20 16.19 + react-syntax-highlighter@15.6.6
#20 16.19 + recharts@2.15.4
#20 16.19 + sharp@0.34.5
#20 16.19 + sonner@2.0.7
#20 16.19 + tailwind-merge@3.7.0
#20 16.19 + tailwindcss-animate@1.0.7
#20 16.19 + uuid@11.1.0
#20 16.19 + vaul@1.1.2
#20 16.19 + z-ai-web-dev-sdk@0.0.18
#20 16.19 + zod@4.3.5
#20 16.19 + zustand@5.0.10
#20 16.19
#20 16.19 858 packages installed [16.07s]
#20 DONE 18.4s
#25 copy / /app
#25 DONE 6.0s
#26 bun run build
#26 4.182 $ prisma generate && next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
#26 5.561 Prisma schema loaded from prisma/schema.prisma
#26 6.699 ┌─────────────────────────────────────────────────────────┐
#26 6.699 │ Update available 6.19.2 -> 8.0.0-rc.28 │
#26 6.699 │ │
#26 6.699 │ This is a major update - please follow the guide at │
#26 6.699 │ https://pris.ly/d/major-version-upgrade │
#26 6.699 │ │
#26 6.699 │ Run the following to update │
#26 6.699 │ npm i --save-dev prisma@latest │
#26 6.699 │ npm i @prisma/client@latest │
#26 6.699 └─────────────────────────────────────────────────────────┘
#26 6.699
#26 6.699 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 642ms
#26 6.699
#26 6.699 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#26 6.699
#26 6.699 Tip: Want to turn off tips and other hints? https://pris.ly/tip-4-nohints
#26 6.699
#26 6.999 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
#26 8.173 ▲ Next.js 16.1.3 (Turbopack)
#26 8.173
#26 8.458 Creating an optimized production build ...
#26 14.23 (node:95) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#26 14.23 (Use `node --trace-deprecation ...` to show where the warning was created)
#26 32.19 ✓ Compiled successfully in 23.2s
#26 32.19 Skipping validation of types
#26 32.45 Collecting page data using 3 workers ...
#26 35.01 Generating static pages using 3 workers (0/4) ...
#26 35.13 Generating static pages using 3 workers (1/4)
#26 35.26 Each child in a list should have a unique "key" prop.
#26 35.26
#26 35.26 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 35.26 Each child in a list should have a unique "key" prop.
#26 35.26
#26 35.26 Check the top-level render call using <M>. See https://react.dev/link/warning-keys for more information.
#26 35.27 Each child in a list should have a unique "key" prop.
#26 35.27
#26 35.27 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 35.28 Each child in a list should have a unique "key" prop.
#26 35.28
#26 35.28 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 35.30 Each child in a list should have a unique "key" prop.
#26 35.30
#26 35.30 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 35.31 Each child in a list should have a unique "key" prop.
#26 35.31
#26 35.31 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 35.31 Each child in a list should have a unique "key" prop.
#26 35.31
#26 35.31 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 35.31 Each child in a list should have a unique "key" prop.
#26 35.31
#26 35.31 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 35.37 Each child in a list should have a unique "key" prop.
#26 35.37
#26 35.37 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 35.37 Each child in a list should have a unique "key" prop.
#26 35.37
#26 35.37 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 35.37 Each child in a list should have a unique "key" prop.
#26 35.37
#26 35.37 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 35.37 Each child in a list should have a unique "key" prop.
#26 35.37
#26 35.37 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 35.39 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
#26 35.39 TypeError: Cannot read properties of null (reading 'useContext')
#26 35.39 at ignore-listed frames {
#26 35.39 digest: '1499178773'
#26 35.39 }
#26 35.39 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
#26 35.49 ⨯ Next.js build worker exited with code: 1 and signal: null
#26 35.60 error: script "build" exited with code 1
#26 ERROR: process "bun run build" did not complete successfully: exit code: 1
------
> bun run build:
35.37
35.37 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
35.39 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
35.39 TypeError: Cannot read properties of null (reading 'useContext')
35.39 at ignore-listed frames {
35.39 digest: '1499178773'
35.39 }
35.39 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
35.49 ⨯ Next.js build worker exited with code: 1 and signal: null
35.60 error: script "build" exited with code 1
------
ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
❌ Railpack build failed
railpack-dfm-aos-lgbcnc-fk4Q2Q removed
Error occurred ❌, check the logs for details.
-444
View File
@@ -1,444 +0,0 @@
Initializing deployment
Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
remote: Enumerating objects: 1878, done.
remote: Counting objects: 0% (1/1878) remote: Counting objects: 1% (19/1878) remote: Counting objects: 2% (38/1878) remote: Counting objects: 3% (57/1878) remote: Counting objects: 4% (76/1878) remote: Counting objects: 5% (94/1878) remote: Counting objects: 6% (113/1878) remote: Counting objects: 7% (132/1878) remote: Counting objects: 8% (151/1878) remote: Counting objects: 9% (170/1878) remote: Counting objects: 10% (188/1878) remote: Counting objects: 11% (207/1878) remote: Counting objects: 12% (226/1878) remote: Counting objects: 13% (245/1878) remote: Counting objects: 14% (263/1878) remote: Counting objects: 15% (282/1878) remote: Counting objects: 16% (301/1878) remote: Counting objects: 17% (320/1878) remote: Counting objects: 18% (339/1878) remote: Counting objects: 19% (357/1878) remote: Counting objects: 20% (376/1878) remote: Counting objects: 21% (395/1878) remote: Counting objects: 22% (414/1878) remote: Counting objects: 23% (432/1878) remote: Counting objects: 24% (451/1878) remote: Counting objects: 25% (470/1878) remote: Counting objects: 26% (489/1878) remote: Counting objects: 27% (508/1878) remote: Counting objects: 28% (526/1878) remote: Counting objects: 29% (545/1878) remote: Counting objects: 30% (564/1878) remote: Counting objects: 31% (583/1878) remote: Counting objects: 32% (601/1878) remote: Counting objects: 33% (620/1878) remote: Counting objects: 34% (639/1878) remote: Counting objects: 35% (658/1878) remote: Counting objects: 36% (677/1878) remote: Counting objects: 37% (695/1878) remote: Counting objects: 38% (714/1878) remote: Counting objects: 39% (733/1878) remote: Counting objects: 40% (752/1878) remote: Counting objects: 41% (770/1878) remote: Counting objects: 42% (789/1878) remote: Counting objects: 43% (808/1878) remote: Counting objects: 44% (827/1878) remote: Counting objects: 45% (846/1878) remote: Counting objects: 46% (864/1878) remote: Counting objects: 47% (883/1878) remote: Counting objects: 48% (902/1878) remote: Counting objects: 49% (921/1878) remote: Counting objects: 50% (939/1878) remote: Counting objects: 51% (958/1878) remote: Counting objects: 52% (977/1878) remote: Counting objects: 53% (996/1878) remote: Counting objects: 54% (1015/1878) remote: Counting objects: 55% (1033/1878) remote: Counting objects: 56% (1052/1878) remote: Counting objects: 57% (1071/1878) remote: Counting objects: 58% (1090/1878) remote: Counting objects: 59% (1109/1878) remote: Counting objects: 60% (1127/1878) remote: Counting objects: 61% (1146/1878) remote: Counting objects: 62% (1165/1878) remote: Counting objects: 63% (1184/1878) remote: Counting objects: 64% (1202/1878) remote: Counting objects: 65% (1221/1878) remote: Counting objects: 66% (1240/1878) remote: Counting objects: 67% (1259/1878) remote: Counting objects: 68% (1278/1878) remote: Counting objects: 69% (1296/1878) remote: Counting objects: 70% (1315/1878) remote: Counting objects: 71% (1334/1878) remote: Counting objects: 72% (1353/1878) remote: Counting objects: 73% (1371/1878) remote: Counting objects: 74% (1390/1878) remote: Counting objects: 75% (1409/1878) remote: Counting objects: 76% (1428/1878) remote: Counting objects: 77% (1447/1878) remote: Counting objects: 78% (1465/1878) remote: Counting objects: 79% (1484/1878) remote: Counting objects: 80% (1503/1878) remote: Counting objects: 81% (1522/1878) remote: Counting objects: 82% (1540/1878) remote: Counting objects: 83% (1559/1878) remote: Counting objects: 84% (1578/1878) remote: Counting objects: 85% (1597/1878) remote: Counting objects: 86% (1616/1878) remote: Counting objects: 87% (1634/1878) remote: Counting objects: 88% (1653/1878) remote: Counting objects: 89% (1672/1878) remote: Counting objects: 90% (1691/1878) remote: Counting objects: 91% (1709/1878) remote: Counting objects: 92% (1728/1878) remote: Counting objects: 93% (1747/1878) remote: Counting objects: 94% (1766/1878) remote: Counting objects: 95% (1785/1878) remote: Counting objects: 96% (1803/1878) remote: Counting objects: 97% (1822/1878) remote: Counting objects: 98% (1841/1878) remote: CouLine truncated
remote: Compressing objects: 0% (1/1407) remote: Compressing objects: 1% (15/1407) remote: Compressing objects: 2% (29/1407) remote: Compressing objects: 3% (43/1407) remote: Compressing objects: 4% (57/1407) remote: Compressing objects: 5% (71/1407) remote: Compressing objects: 6% (85/1407) remote: Compressing objects: 7% (99/1407) remote: Compressing objects: 8% (113/1407) remote: Compressing objects: 9% (127/1407) remote: Compressing objects: 10% (141/1407) remote: Compressing objects: 11% (155/1407) remote: Compressing objects: 12% (169/1407) remote: Compressing objects: 13% (183/1407) remote: Compressing objects: 14% (197/1407) remote: Compressing objects: 15% (212/1407) remote: Compressing objects: 16% (226/1407) remote: Compressing objects: 17% (240/1407) remote: Compressing objects: 18% (254/1407) remote: Compressing objects: 19% (268/1407) remote: Compressing objects: 20% (282/1407) remote: Compressing objects: 21% (296/1407) remote: Compressing objects: 22% (310/1407) remote: Compressing objects: 23% (324/1407) remote: Compressing objects: 24% (338/1407) remote: Compressing objects: 25% (352/1407) remote: Compressing objects: 26% (366/1407) remote: Compressing objects: 27% (380/1407) remote: Compressing objects: 28% (394/1407) remote: Compressing objects: 29% (409/1407) remote: Compressing objects: 30% (423/1407) remote: Compressing objects: 31% (437/1407) remote: Compressing objects: 32% (451/1407) remote: Compressing objects: 33% (465/1407) remote: Compressing objects: 34% (479/1407) remote: Compressing objects: 35% (493/1407) remote: Compressing objects: 36% (507/1407) remote: Compressing objects: 37% (521/1407) remote: Compressing objects: 38% (535/1407) remote: Compressing objects: 39% (549/1407) remote: Compressing objects: 40% (563/1407) remote: Compressing objects: 41% (577/1407) remote: Compressing objects: 42% (591/1407) remote: Compressing objects: 43% (606/1407) remote: Compressing objects: 44% (620/1407) remote: Compressing objects: 45% (634/1407) remote: Compressing objects: 46% (648/1407) remote: Compressing objects: 47% (662/1407) remote: Compressing objects: 48% (676/1407) remote: Compressing objects: 49% (690/1407) remote: Compressing objects: 50% (704/1407) remote: Compressing objects: 51% (718/1407) remote: Compressing objects: 52% (732/1407) remote: Compressing objects: 53% (746/1407) remote: Compressing objects: 54% (760/1407) remote: Compressing objects: 55% (774/1407) remote: Compressing objects: 56% (788/1407) remote: Compressing objects: 57% (802/1407) remote: Compressing objects: 58% (817/1407) remote: Compressing objects: 59% (831/1407) remote: Compressing objects: 60% (845/1407) remote: Compressing objects: 61% (859/1407) remote: Compressing objects: 62% (873/1407) remote: Compressing objects: 63% (887/1407) remote: Compressing objects: 64% (901/1407) remote: Compressing objects: 65% (915/1407) remote: Compressing objects: 66% (929/1407) remote: Compressing objects: 67% (943/1407) remote: Compressing objects: 68% (957/1407) remote: Compressing objects: 69% (971/1407) remote: Compressing objects: 70% (985/1407) remote: Compressing objects: 71% (999/1407) remote: Compressing objects: 72% (1014/1407) remote: Compressing objects: 73% (1028/1407) remote: Compressing objects: 74% (1042/1407) remote: Compressing objects: 75% (1056/1407) remote: Compressing objects: 76% (1070/1407) remote: Compressing objects: 77% (1084/1407) remote: Compressing objects: 78% (1098/1407) remote: Compressing objects: 79% (1112/1407) remote: Compressing objects: 80% (1126/1407) remote: Compressing objects: 81% (1140/1407) remote: Compressing objects: 82% (1154/1407) remote: Compressing objects: 83% (1168/1407) remote: Compressing objects: 84% (1182/1407) remote: Compressing objects: 85% (1196/1407) remote: Compressing objects: 86% (1211/1407) remote: Compressing objects: 87% (1225/1407) remote: Compressing objects: 88% (1239/1407) remote: Compressing objects: 89% (1253/1407) remote: Compressing objects: 90% (1267/1407) remote: Compressing objects: 91% (1281/1407) remote: Compressing objects: 92% (1295/1407) remote: Compressing objects: 93% (1309/1407) remoLine truncated
Receiving objects: 0% (1/1878) Receiving objects: 1% (19/1878) Receiving objects: 2% (38/1878) Receiving objects: 3% (57/1878) Receiving objects: 4% (76/1878) Receiving objects: 5% (94/1878) Receiving objects: 6% (113/1878) Receiving objects: 7% (132/1878) Receiving objects: 8% (151/1878) Receiving objects: 9% (170/1878) Receiving objects: 10% (188/1878) Receiving objects: 11% (207/1878) Receiving objects: 12% (226/1878) Receiving objects: 13% (245/1878) Receiving objects: 14% (263/1878) Receiving objects: 15% (282/1878) Receiving objects: 16% (301/1878) Receiving objects: 17% (320/1878) Receiving objects: 18% (339/1878) Receiving objects: 19% (357/1878) Receiving objects: 20% (376/1878) Receiving objects: 21% (395/1878) Receiving objects: 22% (414/1878) Receiving objects: 23% (432/1878) Receiving objects: 24% (451/1878) Receiving objects: 25% (470/1878) Receiving objects: 26% (489/1878) Receiving objects: 27% (508/1878) Receiving objects: 28% (526/1878) Receiving objects: 29% (545/1878) Receiving objects: 30% (564/1878) Receiving objects: 31% (583/1878) Receiving objects: 32% (601/1878) Receiving objects: 33% (620/1878) Receiving objects: 34% (639/1878) Receiving objects: 35% (658/1878) Receiving objects: 36% (677/1878) Receiving objects: 37% (695/1878) Receiving objects: 38% (714/1878) Receiving objects: 39% (733/1878) Receiving objects: 40% (752/1878) Receiving objects: 41% (770/1878) Receiving objects: 42% (789/1878) Receiving objects: 43% (808/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 44% (827/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 45% (846/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 46% (864/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 47% (883/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 48% (902/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 49% (921/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 50% (939/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 51% (958/1878), 11.57 MiB | 23.12 MiB/s Receiving objects: 51% (974/1878), 26.93 MiB | 26.92 MiB/s Receiving objects: 52% (977/1878), 26.93 MiB | 26.92 MiB/s Receiving objects: 53% (996/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 54% (1015/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 55% (1033/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 56% (1052/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 57% (1071/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 58% (1090/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 59% (1109/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 60% (1127/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 61% (1146/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 62% (1165/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 63% (1184/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 64% (1202/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 65% (1221/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 66% (1240/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 67% (1259/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 68% (1278/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 69% (1296/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 70% (1315/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 71% (1334/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 72% (1353/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 73% (1371/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 74% (1390/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 75% (1409/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 76% (1428/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 77% (1447/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 78% (1465/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 79% (1484/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 80% (1503/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 81% (1522/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 82% (1540/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 83% (1559/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 84% (1578/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 85% (1597/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 86% (1616/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 87% (1634/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 88% (1653/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 89% (1672/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 90% (1691/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 91% (1709/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 92% (1728/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 93% (1747/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 94% (1766/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 95% (1785/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 96% (1803/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 97% (1822/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 98% (1841/1878), 42.80 MiB | 28.53 MiB/s Receiving objects: 99% (1860/1878),Line truncated
Receiving objects: 100% (1878/1878), 42.80 MiB | 28.53 MiB/s␍Receiving objects: 100% (1878/1878), 47.77 MiB | 27.51 MiB/s, done.
Resolving deltas: 0% (0/320)␍Resolving deltas: 1% (4/320)␍Resolving deltas: 2% (7/320)␍Resolving deltas: 3% (10/320)␍Resolving deltas: 4% (13/320)␍Resolving deltas: 5% (16/320)␍Resolving deltas: 6% (20/320)␍Resolving deltas: 7% (23/320)␍Resolving deltas: 8% (26/320)␍Resolving deltas: 9% (29/320)␍Resolving deltas: 10% (32/320)␍Resolving deltas: 11% (36/320)␍Resolving deltas: 12% (39/320)␍Resolving deltas: 13% (42/320)␍Resolving deltas: 14% (45/320)␍Resolving deltas: 15% (48/320)␍Resolving deltas: 16% (52/320)␍Resolving deltas: 17% (55/320)␍Resolving deltas: 18% (58/320)␍Resolving deltas: 19% (61/320)␍Resolving deltas: 20% (64/320)␍Resolving deltas: 21% (68/320)␍Resolving deltas: 22% (71/320)␍Resolving deltas: 23% (74/320)␍Resolving deltas: 24% (77/320)␍Resolving deltas: 25% (80/320)␍Resolving deltas: 26% (84/320)␍Resolving deltas: 27% (87/320)␍Resolving deltas: 28% (91/320)␍Resolving deltas: 29% (93/320)␍Resolving deltas: 30% (96/320)␍Resolving deltas: 31% (100/320)␍Resolving deltas: 32% (104/320)␍Resolving deltas: 33% (106/320)␍Resolving deltas: 34% (110/320)␍Resolving deltas: 35% (112/320)␍Resolving deltas: 36% (116/320)␍Resolving deltas: 37% (119/320)␍Resolving deltas: 38% (122/320)␍Resolving deltas: 39% (125/320)␍Resolving deltas: 40% (128/320)␍Resolving deltas: 41% (132/320)␍Resolving deltas: 42% (135/320)␍Resolving deltas: 43% (138/320)␍Resolving deltas: 44% (141/320)␍Resolving deltas: 45% (144/320)␍Resolving deltas: 46% (149/320)␍Resolving deltas: 47% (151/320)␍Resolving deltas: 48% (154/320)␍Resolving deltas: 49% (157/320)␍Resolving deltas: 50% (160/320)␍Resolving deltas: 51% (164/320)␍Resolving deltas: 52% (167/320)␍Resolving deltas: 53% (170/320)␍Resolving deltas: 54% (173/320)␍Resolving deltas: 55% (176/320)␍Resolving deltas: 56% (180/320)␍Resolving deltas: 57% (183/320)␍Resolving deltas: 58% (186/320)␍Resolving deltas: 59% (189/320)␍Resolving deltas: 60% (192/320)␍Resolving deltas: 61% (196/320)␍Resolving deltas: 62% (199/320)␍Resolving deltas: 63% (202/320)␍Resolving deltas: 64% (205/320)␍Resolving deltas: 65% (208/320)␍Resolving deltas: 66% (212/320)␍Resolving deltas: 67% (215/320)␍Resolving deltas: 68% (218/320)␍Resolving deltas: 69% (221/320)␍Resolving deltas: 70% (224/320)␍Resolving deltas: 71% (228/320)␍Resolving deltas: 72% (231/320)␍Resolving deltas: 73% (234/320)␍Resolving deltas: 74% (237/320)␍Resolving deltas: 75% (240/320)␍Resolving deltas: 76% (244/320)␍Resolving deltas: 77% (247/320)␍Resolving deltas: 78% (250/320)␍Resolving deltas: 79% (253/320)␍Resolving deltas: 80% (256/320)␍Resolving deltas: 81% (260/320)␍Resolving deltas: 82% (263/320)␍Resolving deltas: 83% (266/320)␍Resolving deltas: 84% (269/320)␍Resolving deltas: 85% (272/320)␍Resolving deltas: 86% (276/320)␍Resolving deltas: 87% (279/320)␍Resolving deltas: 88% (282/320)␍Resolving deltas: 89% (285/320)␍Resolving deltas: 90% (288/320)␍Resolving deltas: 91% (292/320)␍Resolving deltas: 92% (295/320)␍Resolving deltas: 93% (298/320)␍Resolving deltas: 94% (301/320)␍Resolving deltas: 95% (304/320)␍Resolving deltas: 96% (308/320)␍Resolving deltas: 97% (311/320)␍Resolving deltas: 98% (314/320)␍Resolving deltas: 99% (317/320)␍Resolving deltas: 100% (320/320)␍Resolving deltas: 100% (320/320), done.
> Installing railpack, please wait…
____ _ _ _
| _ \ __ _(_) |_ __ __ _ ___| | __
| |_) / _` | | | '_ \ / _` |/ __| |/ /
| _ < (_| | | | |_) | (_| | (__| <
|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
|_|
Railpack is now installed!
Run 'railpack --help' to get started
railpack-dfm-aos-lgbcnc-VqdRBM
Preparing Railpack build plan...
╭─────────────────╮
│ Railpack 0.15.4 │
╰─────────────────╯
↳ Found .dockerignore file, applying filters
↳ Detected Node
↳ Using bun package manager
Packages
──────────
bun │ 1.4.4 │ railpack default (latest)
node │ 26.13.0 │ railpack default (latest)
Steps
──────────
▸ install
$ bun install --frozen-lockfile
▸ build
$ bun run build
Deploy
──────────
$ bun run start
✅ Railpack prepare completed.
Building with Railpack frontend...
#0 building with "railpack-dfm-aos-lgbcnc-VqdRBM" instance using docker-container driver
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 1.9s done
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-vqdrbm0
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-vqdrbm0 5.0s done
#1 DONE 7.0s
#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
#2 DONE 5.5s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 done
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 1.05MB / 7.90MB 0.5s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.6s done
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.6s done
#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
#3 DONE 0.8s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.3s done
#3 DONE 1.1s
#4 load build definition from railpack-plan.json
#4 transferring dockerfile:
#4 transferring dockerfile: 5.06kB done
#4 DONE 0.0s
#5 loading .
#5 DONE 0.0s
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest 1.0s done
#7 ...
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 DONE 1.2s
#5 loading .
#5 transferring context: 3.88MB 0.2s
#5 ...
#8 [railpack] loading secrets
#8 resolve docker.io/library/alpine:latest 1.6s done
#8 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.5s done
#8 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 1.3s done
#8 DONE 3.4s
#5 loading .
#5 ...
#9 [railpack] copy secrets hash
#9 DONE 0.2s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.4s done
#7 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.7s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 51.38MB / 237.08MB 2.1s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 36.70MB / 53.72MB 2.1s
#7 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.2s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 8.39MB / 67.81MB 1.4s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 22.68MB / 25.64MB 0.9s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 40.51MB / 53.72MB 2.3s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.17MB / 25.64MB 1.1s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 45.09MB / 53.72MB 2.4s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 12.58MB / 67.81MB 1.8s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 1.1s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 70.25MB / 237.08MB 2.6s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 49.28MB / 53.72MB 2.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 0B / 49.39MB 0.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 82.84MB / 237.08MB 2.9s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 52.43MB / 53.72MB 2.7s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 3.15MB / 49.39MB 0.3s
#7 ...
#10 [railpack] hash used secrets
#10 DONE 0.9s
#11 [railpack] copy used secrets hash
#11 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 2.9s done
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 11.53MB / 49.39MB 0.5s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 16.78MB / 67.81MB 2.4s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 20.97MB / 49.39MB 0.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 96.47MB / 237.08MB 3.2s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 31.46MB / 49.39MB 0.8s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 39.85MB / 49.39MB 0.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 116.39MB / 237.08MB 3.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 44.04MB / 49.39MB 1.1s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 22.02MB / 67.81MB 3.0s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 1.2s done
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 133.17MB / 237.08MB 3.9s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 26.21MB / 67.81MB 3.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 155.19MB / 237.08MB 4.4s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 31.46MB / 67.81MB 3.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 171.97MB / 237.08MB 4.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 189.79MB / 237.08MB 5.0s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 35.65MB / 67.81MB 4.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 205.52MB / 237.08MB 5.3s
#7 ...
#5 loading .
#5 transferring context: 128.44MB 5.9s done
#5 DONE 6.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 225.44MB / 237.08MB 5.6s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 40.89MB / 67.81MB 4.8s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 46.14MB / 67.81MB 5.3s
#7 ...
#12 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#12 resolve ghcr.io/railwayapp/railpack-runtime:latest 1.0s done
#12 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.4s done
#12 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 1.6s done
#12 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 4.2s done
#12 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.7s done
#12 DONE 7.6s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 6.1s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 50.33MB / 67.81MB 5.6s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 54.53MB / 67.81MB 5.9s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 58.72MB / 67.81MB 6.2s
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 3.0s done
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 62.91MB / 67.81MB 6.5s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 6.9s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 6.9s done
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 0.9s done
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 2.8s done
#7 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.2s done
#7 DONE 13.1s
#13 install apt packages: libatomic1
#13 0.216 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
#13 0.284 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#13 0.312 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#13 0.340 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
#13 0.505 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
#13 0.531 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
#13 1.832 Fetched 10.2 MB in 2s (6017 kB/s)
#13 1.832 Reading package lists...
#13 2.970 Reading package lists...
#13 3.978 Building dependency tree...
#13 4.187 Reading state information...
#13 4.644 The following NEW packages will be installed:
#13 4.646 libatomic1
#13 4.771 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
#13 4.771 Need to get 9308 B of archives.
#13 4.771 After this operation, 46.1 kB of additional disk space will be used.
#13 4.771 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
#13 4.966 debconf: unable to initialize frontend: Dialog
#13 4.966 debconf: (TERM is not set, so the dialog frontend is not usable.)
#13 4.966 debconf: falling back to frontend: Readline
#13 4.966 debconf: unable to initialize frontend: Readline
#13 4.966 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
#13 4.966 debconf: falling back to frontend: Teletype
#13 4.974 debconf: unable to initialize frontend: Teletype
#13 4.974 debconf: (This frontend requires a controlling tty.)
#13 4.974 debconf: falling back to frontend: Noninteractive
#13 6.030 Fetched 9308 B in 0s (98.1 kB/s)
#13 6.065 Selecting previously unselected package libatomic1:amd64.
#13 6.065 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
#13 6.073 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
#13 6.083 Unpacking libatomic1:amd64 (14.2.0-19) ...
#13 6.135 Setting up libatomic1:amd64 (14.2.0-19) ...
#13 6.144 Processing triggers for libc-bin (2.41-12+deb13u4) ...
#13 DONE 7.8s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 6.9s done
#7 DONE 20.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
#7 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
#7 DONE 20.0s
#14 mkdir /etc/mise
#14 DONE 1.4s
#15 create mise config
#15 DONE 0.0s
#16 install mise packages: bun, node
#16 0.094 mise by @jdx – installing 2 tools
#16 3.094 mise ███████░░░░░░░░░ 0/2 · 3.0s
#16 3.094 bun@1.4.4 downloading 2.6s 6.8/51.8 MB · 3.0 MB/s
#16 3.094 node@26.13.0 extracting 2.6s
#16 4.859 mise node@26.13.0 v26.13.0
#16 5.016 mise node@26.13.0 11.20.0
#16 5.044 mise ✓ node@26.13.0 4.5s node-v26.13.0-linux-x64.tar.gz
#16 6.094 mise ██████████░░░░░░ 1/2 · 6.0s
#16 6.094 bun@1.4.4 downloading 5.6s 19.8/51.8 MB · 3.7 MB/s
#16 9.094 mise ███████████░░░░░ 1/2 · 9.0s
#16 9.094 bun@1.4.4 downloading 8.6s 34.9/51.8 MB · 4.2 MB/s
#16 12.09 mise ██████████████░░ 1/2 · 12.0s
#16 12.09 bun@1.4.4 extracting 11.6s
#16 12.48 mise bun@1.4.4 1.4.4
#16 12.49 mise ✓ bun@1.4.4 12.0s bun-linux-x64.zip
#16 12.49 mise ████████████████ 2/2 · installed 2 tools in 12.4s
#16 DONE 12.8s
#17 copy / /app
#17 DONE 0.6s
#18 mkdir -p /app/node_modules/.cache
#18 DONE 0.2s
#19 bun install --frozen-lockfile
#19 0.128 bun install v1.4.4 (38afee6c8)
#19 ...
#20 copy /mise/shims
#20 DONE 0.0s
#21 copy /mise/installs
#21 DONE 8.7s
#19 bun install --frozen-lockfile
#19 ...
#22 copy /usr/local/bin/mise
#22 DONE 0.6s
#19 bun install --frozen-lockfile
#19 ...
#23 copy /etc/mise/config.toml
#23 DONE 0.1s
#24 copy /root/.local/state/mise
#24 DONE 0.1s
#19 bun install --frozen-lockfile
#19 14.16
#19 14.17 $ prisma generate || true
#19 16.10 Prisma schema loaded from prisma/schema.prisma
#19 16.88
#19 16.88 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 385ms
#19 16.88
#19 16.88 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#19 16.88
#19 16.88 Tip: Interested in query caching in just a few lines of code? Try Accelerate today! https://pris.ly/tip-3-accelerate
#19 16.88
#19 17.02
#19 17.02 + @tailwindcss/postcss@4.1.18
#19 17.02 + @types/react@19.2.8
#19 17.02 + @types/react-dom@19.2.3
#19 17.02 + bun-types@1.3.6
#19 17.02 + eslint@9.39.2
#19 17.02 + eslint-config-next@16.1.3
#19 17.02 + tailwindcss@4.1.18
#19 17.02 + tw-animate-css@1.4.0
#19 17.02 + typescript@5.9.3
#19 17.02 + @dnd-kit/core@6.3.1
#19 17.02 + @dnd-kit/sortable@10.0.0
#19 17.02 + @dnd-kit/utilities@3.2.2
#19 17.02 + @hookform/resolvers@5.2.2
#19 17.02 + @hugeicons/core-free-icons@4.3.5
#19 17.02 + @hugeicons/react@1.1.10
#19 17.02 + @mdxeditor/editor@3.52.3
#19 17.02 + @prisma/client@6.19.2
#19 17.02 + @radix-ui/react-accordion@1.2.12
#19 17.02 + @radix-ui/react-alert-dialog@1.1.15
#19 17.02 + @radix-ui/react-aspect-ratio@1.1.8
#19 17.02 + @radix-ui/react-avatar@1.1.11
#19 17.02 + @radix-ui/react-checkbox@1.3.3
#19 17.02 + @radix-ui/react-collapsible@1.1.12
#19 17.02 + @radix-ui/react-context-menu@2.2.16
#19 17.02 + @radix-ui/react-dialog@1.1.15
#19 17.02 + @radix-ui/react-dropdown-menu@2.1.16
#19 17.02 + @radix-ui/react-hover-card@1.1.15
#19 17.02 + @radix-ui/react-label@2.1.8
#19 17.02 + @radix-ui/react-menubar@1.1.16
#19 17.02 + @radix-ui/react-navigation-menu@1.2.14
#19 17.02 + @radix-ui/react-popover@1.1.15
#19 17.02 + @radix-ui/react-progress@1.1.8
#19 17.02 + @radix-ui/react-radio-group@1.3.8
#19 17.02 + @radix-ui/react-scroll-area@1.2.10
#19 17.02 + @radix-ui/react-select@2.2.6
#19 17.02 + @radix-ui/react-separator@1.1.8
#19 17.02 + @radix-ui/react-slider@1.3.6
#19 17.02 + @radix-ui/react-slot@1.2.4
#19 17.02 + @radix-ui/react-switch@1.2.6
#19 17.02 + @radix-ui/react-tabs@1.1.13
#19 17.02 + @radix-ui/react-toast@1.2.15
#19 17.02 + @radix-ui/react-toggle@1.1.10
#19 17.02 + @radix-ui/react-toggle-group@1.1.11
#19 17.02 + @radix-ui/react-tooltip@1.2.8
#19 17.02 + @reactuses/core@6.1.9
#19 17.02 + @tanstack/react-query@5.90.19
#19 17.02 + @tanstack/react-table@8.21.3
#19 17.02 + class-variance-authority@0.7.1
#19 17.02 + clsx@2.1.1
#19 17.02 + cmdk@1.1.1
#19 17.02 + date-fns@4.1.0
#19 17.02 + embla-carousel-react@8.6.0
#19 17.02 + framer-motion@14.7.1
#19 17.02 + imapflow@2.9.1
#19 17.02 + input-otp@1.4.2
#19 17.02 + lucide-react@1.62.0
#19 17.02 + motion@12.43.0
#19 17.02 + next@16.1.3
#19 17.02 + next-auth@4.24.13
#19 17.02 + next-intl@4.7.0
#19 17.02 + next-themes@0.4.6
#19 17.02 + prisma@6.19.2
#19 17.02 + react@19.2.3
#19 17.02 + react-day-picker@9.13.0
#19 17.02 + react-dom@19.2.3
#19 17.02 + react-hook-form@7.71.1
#19 17.02 + react-markdown@10.1.0
#19 17.02 + react-resizable-panels@3.0.6
#19 17.02 + react-syntax-highlighter@15.6.6
#19 17.02 + recharts@2.15.4
#19 17.02 + sharp@0.34.5
#19 17.02 + sonner@2.0.7
#19 17.02 + tailwind-merge@3.7.0
#19 17.02 + tailwindcss-animate@1.0.7
#19 17.02 + uuid@11.1.0
#19 17.02 + vaul@1.1.2
#19 17.02 + z-ai-web-dev-sdk@0.0.18
#19 17.02 + zod@4.3.5
#19 17.02 + zustand@5.0.10
#19 17.02
#19 17.02 858 packages installed [16.89s]
#19 DONE 18.8s
#25 copy / /app
#25 DONE 9.1s
#26 bun run build
#26 0.237 $ prisma generate && next build && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
#26 1.867 Prisma schema loaded from prisma/schema.prisma
#26 2.793 ┌─────────────────────────────────────────────────────────┐
#26 2.793 │ Update available 6.19.2 -> 8.0.0-rc.28 │
#26 2.793 │ │
#26 2.793 │ This is a major update - please follow the guide at │
#26 2.793 │ https://pris.ly/d/major-version-upgrade │
#26 2.793 │ │
#26 2.793 │ Run the following to update │
#26 2.793 │ npm i --save-dev prisma@latest │
#26 2.793 │ npm i @prisma/client@latest │
#26 2.793 └─────────────────────────────────────────────────────────┘
#26 2.794
#26 2.794 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 473ms
#26 2.794
#26 2.794 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#26 2.794
#26 2.794 Tip: Interested in query caching in just a few lines of code? Try Accelerate today! https://pris.ly/tip-3-accelerate
#26 2.794
#26 3.028 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
#26 5.015 ▲ Next.js 16.1.3 (Turbopack)
#26 5.016
#26 5.180 Creating an optimized production build ...
#26 13.50 (node:123) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#26 13.50 (Use `node --trace-deprecation ...` to show where the warning was created)
#26 31.44 ✓ Compiled successfully in 25.1s
#26 31.45 Skipping validation of types
#26 31.84 Collecting page data using 3 workers ...
#26 33.48 Generating static pages using 3 workers (0/4) ...
#26 33.60 Generating static pages using 3 workers (1/4)
#26 33.71 Each child in a list should have a unique "key" prop.
#26 33.71
#26 33.71 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 33.72 Each child in a list should have a unique "key" prop.
#26 33.72
#26 33.72 Check the top-level render call using <M>. See https://react.dev/link/warning-keys for more information.
#26 33.73 Each child in a list should have a unique "key" prop.
#26 33.73
#26 33.73 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 33.73 Each child in a list should have a unique "key" prop.
#26 33.73
#26 33.73 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 33.76 Each child in a list should have a unique "key" prop.
#26 33.76
#26 33.76 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 33.76 Each child in a list should have a unique "key" prop.
#26 33.76
#26 33.76 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 33.77 Each child in a list should have a unique "key" prop.
#26 33.77
#26 33.77 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 33.77 Each child in a list should have a unique "key" prop.
#26 33.77
#26 33.77 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 33.84 Each child in a list should have a unique "key" prop.
#26 33.84
#26 33.84 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 33.84 Each child in a list should have a unique "key" prop.
#26 33.84
#26 33.84 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 33.84 Each child in a list should have a unique "key" prop.
#26 33.84
#26 33.84 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 33.84 Each child in a list should have a unique "key" prop.
#26 33.84
#26 33.84 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 33.86 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
#26 33.86 TypeError: Cannot read properties of null (reading 'useContext')
#26 33.86 at ignore-listed frames {
#26 33.86 digest: '1499178773'
#26 33.86 }
#26 33.86 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
#26 33.91 ⨯ Next.js build worker exited with code: 1 and signal: null
#26 33.98 error: script "build" exited with code 1
#26 ERROR: process "bun run build" did not complete successfully: exit code: 1
------
> bun run build:
33.84
33.84 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
33.86 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
33.86 TypeError: Cannot read properties of null (reading 'useContext')
33.86 at ignore-listed frames {
33.86 digest: '1499178773'
33.86 }
33.86 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
33.91 ⨯ Next.js build worker exited with code: 1 and signal: null
33.98 error: script "build" exited with code 1
------
ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
❌ Railpack build failed
railpack-dfm-aos-lgbcnc-VqdRBM removed
Error occurred ❌, check the logs for details.
-467
View File
@@ -1,467 +0,0 @@
Initializing deployment
Cloning Repo github.com/cetinmustafa83/aos.git to /etc/dokploy/applications/dfm-aos-lgbcnc/code: ✅
Cloning into '/etc/dokploy/applications/dfm-aos-lgbcnc/code'...
remote: Enumerating objects: 1879, done.
remote: Counting objects: 0% (1/1879) remote: Counting objects: 1% (19/1879) remote: Counting objects: 2% (38/1879) remote: Counting objects: 3% (57/1879) remote: Counting objects: 4% (76/1879) remote: Counting objects: 5% (94/1879) remote: Counting objects: 6% (113/1879) remote: Counting objects: 7% (132/1879) remote: Counting objects: 8% (151/1879) remote: Counting objects: 9% (170/1879) remote: Counting objects: 10% (188/1879) remote: Counting objects: 11% (207/1879) remote: Counting objects: 12% (226/1879) remote: Counting objects: 13% (245/1879) remote: Counting objects: 14% (264/1879) remote: Counting objects: 15% (282/1879) remote: Counting objects: 16% (301/1879) remote: Counting objects: 17% (320/1879) remote: Counting objects: 18% (339/1879) remote: Counting objects: 19% (358/1879) remote: Counting objects: 20% (376/1879) remote: Counting objects: 21% (395/1879) remote: Counting objects: 22% (414/1879) remote: Counting objects: 23% (433/1879) remote: Counting objects: 24% (451/1879) remote: Counting objects: 25% (470/1879) remote: Counting objects: 26% (489/1879) remote: Counting objects: 27% (508/1879) remote: Counting objects: 28% (527/1879) remote: Counting objects: 29% (545/1879) remote: Counting objects: 30% (564/1879) remote: Counting objects: 31% (583/1879) remote: Counting objects: 32% (602/1879) remote: Counting objects: 33% (621/1879) remote: Counting objects: 34% (639/1879) remote: Counting objects: 35% (658/1879) remote: Counting objects: 36% (677/1879) remote: Counting objects: 37% (696/1879) remote: Counting objects: 38% (715/1879) remote: Counting objects: 39% (733/1879) remote: Counting objects: 40% (752/1879) remote: Counting objects: 41% (771/1879) remote: Counting objects: 42% (790/1879) remote: Counting objects: 43% (808/1879) remote: Counting objects: 44% (827/1879) remote: Counting objects: 45% (846/1879) remote: Counting objects: 46% (865/1879) remote: Counting objects: 47% (884/1879) remote: Counting objects: 48% (902/1879) remote: Counting objects: 49% (921/1879) remote: Counting objects: 50% (940/1879) remote: Counting objects: 51% (959/1879) remote: Counting objects: 52% (978/1879) remote: Counting objects: 53% (996/1879) remote: Counting objects: 54% (1015/1879) remote: Counting objects: 55% (1034/1879) remote: Counting objects: 56% (1053/1879) remote: Counting objects: 57% (1072/1879) remote: Counting objects: 58% (1090/1879) remote: Counting objects: 59% (1109/1879) remote: Counting objects: 60% (1128/1879) remote: Counting objects: 61% (1147/1879) remote: Counting objects: 62% (1165/1879) remote: Counting objects: 63% (1184/1879) remote: Counting objects: 64% (1203/1879) remote: Counting objects: 65% (1222/1879) remote: Counting objects: 66% (1241/1879) remote: Counting objects: 67% (1259/1879) remote: Counting objects: 68% (1278/1879) remote: Counting objects: 69% (1297/1879) remote: Counting objects: 70% (1316/1879) remote: Counting objects: 71% (1335/1879) remote: Counting objects: 72% (1353/1879) remote: Counting objects: 73% (1372/1879) remote: Counting objects: 74% (1391/1879) remote: Counting objects: 75% (1410/1879) remote: Counting objects: 76% (1429/1879) remote: Counting objects: 77% (1447/1879) remote: Counting objects: 78% (1466/1879) remote: Counting objects: 79% (1485/1879) remote: Counting objects: 80% (1504/1879) remote: Counting objects: 81% (1522/1879) remote: Counting objects: 82% (1541/1879) remote: Counting objects: 83% (1560/1879) remote: Counting objects: 84% (1579/1879) remote: Counting objects: 85% (1598/1879) remote: Counting objects: 86% (1616/1879) remote: Counting objects: 87% (1635/1879) remote: Counting objects: 88% (1654/1879) remote: Counting objects: 89% (1673/1879) remote: Counting objects: 90% (1692/1879) remote: Counting objects: 91% (1710/1879) remote: Counting objects: 92% (1729/1879) remote: Counting objects: 93% (1748/1879) remote: Counting objects: 94% (1767/1879) remote: Counting objects: 95% (1786/1879) remote: Counting objects: 96% (1804/1879) remote: Counting objects: 97% (1823/1879) remote: Counting objects: 98% (1842/1879) remote: CouLine truncated
remote: Compressing objects: 0% (1/1408) remote: Compressing objects: 1% (15/1408) remote: Compressing objects: 2% (29/1408) remote: Compressing objects: 3% (43/1408) remote: Compressing objects: 4% (57/1408) remote: Compressing objects: 5% (71/1408) remote: Compressing objects: 6% (85/1408) remote: Compressing objects: 7% (99/1408) remote: Compressing objects: 8% (113/1408) remote: Compressing objects: 9% (127/1408) remote: Compressing objects: 10% (141/1408) remote: Compressing objects: 11% (155/1408) remote: Compressing objects: 12% (169/1408) remote: Compressing objects: 13% (184/1408) remote: Compressing objects: 14% (198/1408) remote: Compressing objects: 15% (212/1408) remote: Compressing objects: 16% (226/1408) remote: Compressing objects: 17% (240/1408) remote: Compressing objects: 18% (254/1408) remote: Compressing objects: 19% (268/1408) remote: Compressing objects: 20% (282/1408) remote: Compressing objects: 21% (296/1408) remote: Compressing objects: 22% (310/1408) remote: Compressing objects: 23% (324/1408) remote: Compressing objects: 24% (338/1408) remote: Compressing objects: 25% (352/1408) remote: Compressing objects: 26% (367/1408) remote: Compressing objects: 27% (381/1408) remote: Compressing objects: 28% (395/1408) remote: Compressing objects: 29% (409/1408) remote: Compressing objects: 30% (423/1408) remote: Compressing objects: 31% (437/1408) remote: Compressing objects: 32% (451/1408) remote: Compressing objects: 33% (465/1408) remote: Compressing objects: 34% (479/1408) remote: Compressing objects: 35% (493/1408) remote: Compressing objects: 36% (507/1408) remote: Compressing objects: 37% (521/1408) remote: Compressing objects: 38% (536/1408) remote: Compressing objects: 39% (550/1408) remote: Compressing objects: 40% (564/1408) remote: Compressing objects: 41% (578/1408) remote: Compressing objects: 42% (592/1408) remote: Compressing objects: 43% (606/1408) remote: Compressing objects: 44% (620/1408) remote: Compressing objects: 45% (634/1408) remote: Compressing objects: 46% (648/1408) remote: Compressing objects: 47% (662/1408) remote: Compressing objects: 48% (676/1408) remote: Compressing objects: 49% (690/1408) remote: Compressing objects: 50% (704/1408) remote: Compressing objects: 51% (719/1408) remote: Compressing objects: 52% (733/1408) remote: Compressing objects: 53% (747/1408) remote: Compressing objects: 54% (761/1408) remote: Compressing objects: 55% (775/1408) remote: Compressing objects: 56% (789/1408) remote: Compressing objects: 57% (803/1408) remote: Compressing objects: 58% (817/1408) remote: Compressing objects: 59% (831/1408) remote: Compressing objects: 60% (845/1408) remote: Compressing objects: 61% (859/1408) remote: Compressing objects: 62% (873/1408) remote: Compressing objects: 63% (888/1408) remote: Compressing objects: 64% (902/1408) remote: Compressing objects: 65% (916/1408) remote: Compressing objects: 66% (930/1408) remote: Compressing objects: 67% (944/1408) remote: Compressing objects: 68% (958/1408) remote: Compressing objects: 69% (972/1408) remote: Compressing objects: 70% (986/1408) remote: Compressing objects: 71% (1000/1408) remote: Compressing objects: 72% (1014/1408) remote: Compressing objects: 73% (1028/1408) remote: Compressing objects: 74% (1042/1408) remote: Compressing objects: 75% (1056/1408) remote: Compressing objects: 76% (1071/1408) remote: Compressing objects: 77% (1085/1408) remote: Compressing objects: 78% (1099/1408) remote: Compressing objects: 79% (1113/1408) remote: Compressing objects: 80% (1127/1408) remote: Compressing objects: 81% (1141/1408) remote: Compressing objects: 82% (1155/1408) remote: Compressing objects: 83% (1169/1408) remote: Compressing objects: 84% (1183/1408) remote: Compressing objects: 85% (1197/1408) remote: Compressing objects: 86% (1211/1408) remote: Compressing objects: 87% (1225/1408) remote: Compressing objects: 88% (1240/1408) remote: Compressing objects: 89% (1254/1408) remote: Compressing objects: 90% (1268/1408) remote: Compressing objects: 91% (1282/1408) remote: Compressing objects: 92% (1296/1408) remote: Compressing objects: 93% (1310/1408) remLine truncated
Receiving objects: 0% (1/1879) Receiving objects: 1% (19/1879) Receiving objects: 2% (38/1879) Receiving objects: 3% (57/1879) Receiving objects: 4% (76/1879) Receiving objects: 5% (94/1879) Receiving objects: 6% (113/1879) Receiving objects: 7% (132/1879) Receiving objects: 8% (151/1879) Receiving objects: 9% (170/1879) Receiving objects: 10% (188/1879) Receiving objects: 11% (207/1879) Receiving objects: 12% (226/1879) Receiving objects: 13% (245/1879) Receiving objects: 14% (264/1879) Receiving objects: 15% (282/1879) Receiving objects: 16% (301/1879) Receiving objects: 17% (320/1879) Receiving objects: 18% (339/1879) Receiving objects: 19% (358/1879) Receiving objects: 20% (376/1879) Receiving objects: 21% (395/1879) Receiving objects: 22% (414/1879) Receiving objects: 23% (433/1879) Receiving objects: 24% (451/1879) Receiving objects: 25% (470/1879) Receiving objects: 26% (489/1879) Receiving objects: 27% (508/1879) Receiving objects: 28% (527/1879) Receiving objects: 29% (545/1879) Receiving objects: 30% (564/1879) Receiving objects: 31% (583/1879) Receiving objects: 32% (602/1879) Receiving objects: 33% (621/1879) Receiving objects: 34% (639/1879) Receiving objects: 35% (658/1879) Receiving objects: 36% (677/1879) Receiving objects: 37% (696/1879) Receiving objects: 38% (715/1879) Receiving objects: 39% (733/1879) Receiving objects: 40% (752/1879) Receiving objects: 41% (771/1879) Receiving objects: 42% (790/1879) Receiving objects: 43% (808/1879) Receiving objects: 44% (827/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 45% (846/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 46% (865/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 47% (884/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 48% (902/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 49% (921/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 50% (940/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 51% (959/1879), 13.46 MiB | 26.90 MiB/s Receiving objects: 51% (974/1879), 29.06 MiB | 29.05 MiB/s Receiving objects: 52% (978/1879), 29.06 MiB | 29.05 MiB/s Receiving objects: 53% (996/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 54% (1015/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 55% (1034/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 56% (1053/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 57% (1072/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 58% (1090/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 59% (1109/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 60% (1128/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 61% (1147/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 62% (1165/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 63% (1184/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 64% (1203/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 65% (1222/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 66% (1241/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 67% (1259/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 68% (1278/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 69% (1297/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 70% (1316/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 71% (1335/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 72% (1353/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 73% (1372/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 74% (1391/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 75% (1410/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 76% (1429/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 77% (1447/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 78% (1466/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 79% (1485/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 80% (1504/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 81% (1522/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 82% (1541/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 83% (1560/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 84% (1579/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 85% (1598/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 86% (1616/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 87% (1635/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 88% (1654/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 89% (1673/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 90% (1692/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 91% (1710/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 92% (1729/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 93% (1748/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 94% (1767/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 95% (1786/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 96% (1804/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 97% (1823/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 98% (1842/1879), 44.77 MiB | 29.84 MiB/s Receiving objects: 99% (1861/1879), 44.77 MiB | 29.84 MiB/s Line truncated
Receiving objects: 100% (1879/1879), 44.77 MiB | 29.84 MiB/s␍Receiving objects: 100% (1879/1879), 47.78 MiB | 29.14 MiB/s, done.
Resolving deltas: 0% (0/320)␍Resolving deltas: 1% (4/320)␍Resolving deltas: 2% (7/320)␍Resolving deltas: 3% (10/320)␍Resolving deltas: 4% (13/320)␍Resolving deltas: 5% (16/320)␍Resolving deltas: 6% (20/320)␍Resolving deltas: 7% (23/320)␍Resolving deltas: 8% (26/320)␍Resolving deltas: 9% (29/320)␍Resolving deltas: 10% (32/320)␍Resolving deltas: 11% (36/320)␍Resolving deltas: 12% (39/320)␍Resolving deltas: 13% (42/320)␍Resolving deltas: 14% (45/320)␍Resolving deltas: 15% (48/320)␍Resolving deltas: 16% (52/320)␍Resolving deltas: 17% (55/320)␍Resolving deltas: 18% (58/320)␍Resolving deltas: 19% (61/320)␍Resolving deltas: 20% (64/320)␍Resolving deltas: 21% (68/320)␍Resolving deltas: 22% (71/320)␍Resolving deltas: 23% (74/320)␍Resolving deltas: 24% (77/320)␍Resolving deltas: 25% (80/320)␍Resolving deltas: 26% (84/320)␍Resolving deltas: 27% (87/320)␍Resolving deltas: 28% (90/320)␍Resolving deltas: 29% (93/320)␍Resolving deltas: 30% (96/320)␍Resolving deltas: 31% (100/320)␍Resolving deltas: 32% (103/320)␍Resolving deltas: 33% (106/320)␍Resolving deltas: 34% (109/320)␍Resolving deltas: 35% (112/320)␍Resolving deltas: 36% (116/320)␍Resolving deltas: 37% (120/320)␍Resolving deltas: 38% (122/320)␍Resolving deltas: 39% (125/320)␍Resolving deltas: 40% (128/320)␍Resolving deltas: 41% (132/320)␍Resolving deltas: 42% (135/320)␍Resolving deltas: 43% (138/320)␍Resolving deltas: 44% (142/320)␍Resolving deltas: 45% (144/320)␍Resolving deltas: 46% (148/320)␍Resolving deltas: 47% (151/320)␍Resolving deltas: 48% (155/320)␍Resolving deltas: 49% (157/320)␍Resolving deltas: 50% (160/320)␍Resolving deltas: 51% (164/320)␍Resolving deltas: 52% (167/320)␍Resolving deltas: 53% (170/320)␍Resolving deltas: 54% (173/320)␍Resolving deltas: 55% (176/320)␍Resolving deltas: 56% (180/320)␍Resolving deltas: 57% (183/320)␍Resolving deltas: 58% (186/320)␍Resolving deltas: 59% (189/320)␍Resolving deltas: 60% (192/320)␍Resolving deltas: 61% (197/320)␍Resolving deltas: 62% (199/320)␍Resolving deltas: 63% (202/320)␍Resolving deltas: 64% (205/320)␍Resolving deltas: 65% (208/320)␍Resolving deltas: 66% (212/320)␍Resolving deltas: 67% (215/320)␍Resolving deltas: 68% (218/320)␍Resolving deltas: 69% (221/320)␍Resolving deltas: 70% (224/320)␍Resolving deltas: 71% (228/320)␍Resolving deltas: 72% (231/320)␍Resolving deltas: 73% (234/320)␍Resolving deltas: 74% (237/320)␍Resolving deltas: 75% (240/320)␍Resolving deltas: 76% (244/320)␍Resolving deltas: 77% (247/320)␍Resolving deltas: 78% (250/320)␍Resolving deltas: 79% (253/320)␍Resolving deltas: 80% (256/320)␍Resolving deltas: 81% (260/320)␍Resolving deltas: 82% (263/320)␍Resolving deltas: 83% (266/320)␍Resolving deltas: 84% (269/320)␍Resolving deltas: 85% (272/320)␍Resolving deltas: 86% (276/320)␍Resolving deltas: 87% (279/320)␍Resolving deltas: 88% (282/320)␍Resolving deltas: 89% (285/320)␍Resolving deltas: 90% (288/320)␍Resolving deltas: 91% (292/320)␍Resolving deltas: 92% (295/320)␍Resolving deltas: 93% (298/320)␍Resolving deltas: 94% (301/320)␍Resolving deltas: 95% (304/320)␍Resolving deltas: 96% (308/320)␍Resolving deltas: 97% (311/320)␍Resolving deltas: 98% (314/320)␍Resolving deltas: 99% (317/320)␍Resolving deltas: 100% (320/320)␍Resolving deltas: 100% (320/320), done.
> Installing railpack, please wait…
____ _ _ _
| _ \ __ _(_) |_ __ __ _ ___| | __
| |_) / _` | | | '_ \ / _` |/ __| |/ /
| _ < (_| | | | |_) | (_| | (__| <
|_| \_\__,_|_|_| .__/ \__,_|\___|_|\_\
|_|
Railpack is now installed!
Run 'railpack --help' to get started
railpack-dfm-aos-lgbcnc-2Y1SV3
Preparing Railpack build plan...
╭─────────────────╮
│ Railpack 0.15.4 │
╰─────────────────╯
↳ Found .dockerignore file, applying filters
↳ Detected Node
↳ Using bun package manager
Packages
──────────
bun │ 1.4.4 │ railpack default (latest)
node │ 26.13.0 │ railpack default (latest)
Steps
──────────
▸ install
$ bun install --frozen-lockfile
▸ build
$ bun run build
Deploy
──────────
$ bun run start
✅ Railpack prepare completed.
Building with Railpack frontend...
#0 building with "railpack-dfm-aos-lgbcnc-2Y1SV3" instance using docker-container driver
#1 [internal] booting buildkit
#1 pulling image moby/buildkit:buildx-stable-1
#1 pulling image moby/buildkit:buildx-stable-1 1.1s done
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-2y1sv30
#1 creating container buildx_buildkit_railpack-dfm-aos-lgbcnc-2y1sv30 0.8s done
#1 DONE 1.8s
#2 resolve image config for docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4
#2 DONE 1.3s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 resolve ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7 done
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0B / 7.90MB 0.2s
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0B / 3.86MB 0.2s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 6.29MB / 7.90MB 0.4s
#3 sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 7.90MB / 7.90MB 0.5s done
#3 sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 3.86MB / 3.86MB 0.7s done
#3 extracting sha256:1074353eec0db2c1d81d5af2671e56e00cf5738486f5762609ea33d606f88612 0.1s done
#3 DONE 0.8s
#3 docker-image://ghcr.io/railwayapp/railpack-frontend:v0.15.4@sha256:7e0535e519d9d00793d0bb4e652be5d48373ab5e0c7d9b90ef6bc40147290ff7
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849
#3 extracting sha256:76fdf18f436616aff2234f2d325d888d31af103f333a8f491d539dce0106e849 0.2s done
#3 DONE 1.0s
#4 load build definition from railpack-plan.json
#4 transferring dockerfile: 5.06kB done
#4 DONE 0.0s
#5 loading .
#5 DONE 0.0s
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest
#7 ...
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 resolve ghcr.io/railwayapp/railpack-runtime:latest 1.0s done
#8 DONE 1.0s
#6 [railpack] secrets hash
#6 DONE 0.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 resolve ghcr.io/railwayapp/railpack-builder:latest 1.0s done
#7 DONE 1.1s
#5 loading .
#5 transferring context: 32B
#5 ...
#9 [railpack] loading secrets
#9 resolve docker.io/library/alpine:latest 1.6s done
#9 DONE 1.6s
#5 loading .
#5 ...
#9 [railpack] loading secrets
#9 sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 3.85MB / 3.85MB 0.5s done
#9 extracting sha256:7b229517ed222597277036d94892173207d01a731ab3a88eeb1de2e963a2c788 0.2s done
#9 DONE 2.3s
#5 loading .
#5 ...
#10 [railpack] copy secrets hash
#10 DONE 0.4s
#5 loading .
#5 ...
#11 [railpack] hash used secrets
#11 DONE 0.6s
#5 loading .
#5 ...
#12 [railpack] copy used secrets hash
#12 DONE 0.0s
#5 loading .
#5 transferring context: 128.50MB 3.1s done
#5 DONE 3.1s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def 119B / 119B 0.4s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 3.15MB / 237.08MB 3.0s
#7 sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 868.40kB / 868.40kB 0.4s done
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 46.14MB / 53.72MB 2.7s
#7 sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.2s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 62.91MB / 67.81MB 2.1s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 8.39MB / 25.64MB 2.0s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 52.43MB / 53.72MB 2.9s
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.11MB / 67.81MB 2.3s
#7 sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 53.72MB / 53.72MB 2.9s done
#7 sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 67.81MB / 67.81MB 2.4s done
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 10.49MB / 25.64MB 2.3s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 13.63MB / 25.64MB 2.4s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 0B / 49.39MB 0.2s
#7 ...
#8 docker-image://ghcr.io/railwayapp/railpack-runtime:latest
#8 sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 7.39MB / 7.39MB 0.4s done
#8 sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 29.84MB / 29.84MB 1.2s done
#8 extracting sha256:ecc510c1e359bdc007b39802570bb7e4dec7d6ebccf357c3201a74299113e05e 2.3s done
#8 extracting sha256:75dc09925ca146a3efecc887098f8f1313da0fb1b0c8d36d628b6cae320665ec 0.3s done
#8 DONE 4.8s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 17.83MB / 25.64MB 2.6s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 22.02MB / 25.64MB 2.7s
#7 sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 25.64MB / 25.64MB 2.8s done
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 7.34MB / 49.39MB 0.6s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 10.49MB / 49.39MB 0.8s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 14.68MB / 49.39MB 1.2s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 17.83MB / 49.39MB 1.4s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 20.97MB / 49.39MB 1.5s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 24.12MB / 49.39MB 1.7s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 31.46MB / 49.39MB 1.8s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 34.60MB / 49.39MB 2.0s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 39.85MB / 49.39MB 2.1s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 45.09MB / 49.39MB 2.3s
#7 sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 49.39MB / 49.39MB 2.5s done
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 5.24MB / 237.08MB 8.1s
#7 extracting sha256:4846f29007305297af653c57bf9b60ba8f676a38695c68d98460063442581671 2.7s done
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d
#7 extracting sha256:62fe2e747f69f2f414c7e9eb1553155cf0a658398f0462557f458821dce2b29d 1.4s done
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af
#7 ...
#13 install apt packages: libatomic1
#13 0.204 Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
#13 0.299 Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
#13 0.324 Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
#13 0.346 Get:4 http://deb.debian.org/debian trixie/main amd64 Packages [9678 kB]
#13 0.508 Get:5 http://deb.debian.org/debian trixie-updates/main amd64 Packages [720 B]
#13 0.532 Get:6 http://deb.debian.org/debian-security trixie-security/main amd64 Packages [270 kB]
#13 1.526 Fetched 10.2 MB in 1s (7253 kB/s)
#13 1.526 Reading package lists...
#13 2.397 Reading package lists...
#13 3.642 Building dependency tree...
#13 3.987 Reading state information...
#13 4.552 The following NEW packages will be installed:
#13 4.555 libatomic1
#13 4.689 0 upgraded, 1 newly installed, 0 to remove and 3 not upgraded.
#13 4.689 Need to get 9308 B of archives.
#13 4.689 After this operation, 46.1 kB of additional disk space will be used.
#13 4.689 Get:1 http://deb.debian.org/debian trixie/main amd64 libatomic1 amd64 14.2.0-19 [9308 B]
#13 4.903 debconf: unable to initialize frontend: Dialog
#13 4.903 debconf: (TERM is not set, so the dialog frontend is not usable.)
#13 4.903 debconf: falling back to frontend: Readline
#13 4.904 debconf: unable to initialize frontend: Readline
#13 4.904 debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC entries checked: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.40.1 /usr/local/share/perl/5.40.1 /usr/lib/x86_64-linux-gnu/perl5/5.40 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.40 /usr/share/perl/5.40 /usr/local/lib/site_perl) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 8, <STDIN> line 1.)
#13 4.904 debconf: falling back to frontend: Teletype
#13 4.912 debconf: unable to initialize frontend: Teletype
#13 4.912 debconf: (This frontend requires a controlling tty.)
#13 4.912 debconf: falling back to frontend: Noninteractive
#13 6.225 Fetched 9308 B in 0s (87.3 kB/s)
#13 6.291 Selecting previously unselected package libatomic1:amd64.
#13 6.291 (Reading database ... ␍(Reading database ... 5%␍(Reading database ... 10%␍(Reading database ... 15%␍(Reading database ... 20%␍(Reading database ... 25%␍(Reading database ... 30%␍(Reading database ... 35%␍(Reading database ... 40%␍(Reading database ... 45%␍(Reading database ... 50%␍(Reading database ... 55%␍(Reading database ... 60%␍(Reading database ... 65%␍(Reading database ... 70%␍(Reading database ... 75%␍(Reading database ... 80%␍(Reading database ... 85%␍(Reading database ... 90%␍(Reading database ... 95%␍(Reading database ... 100%␍(Reading database ... 6228 files and directories currently installed.)
#13 6.308 Preparing to unpack .../libatomic1_14.2.0-19_amd64.deb ...
#13 6.312 Unpacking libatomic1:amd64 (14.2.0-19) ...
#13 6.363 Setting up libatomic1:amd64 (14.2.0-19) ...
#13 6.383 Processing triggers for libc-bin (2.41-12+deb13u4) ...
#13 DONE 7.0s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 6.29MB / 237.08MB 13.2s
#7 extracting sha256:4dc3950125ebc9ed195e1101fc6c02e2fce113ba0f53bfb05b2cdf58747df9af 3.8s done
#7 extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 done
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d
#7 extracting sha256:08a1e03b3da5bb4a1059032dca3216f33ddfc4a48a45db88921f5bb2e9a8fa2d 1.1s done
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 9.44MB / 237.08MB 18.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 20.97MB / 237.08MB 23.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 23.07MB / 237.08MB 28.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 25.17MB / 237.08MB 33.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 26.21MB / 237.08MB 38.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 28.31MB / 237.08MB 43.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 30.41MB / 237.08MB 48.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 31.46MB / 237.08MB 54.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 34.60MB / 237.08MB 59.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 36.70MB / 237.08MB 64.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 38.80MB / 237.08MB 69.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 56.62MB / 237.08MB 73.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 69.21MB / 237.08MB 74.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 74.45MB / 237.08MB 79.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 76.55MB / 237.08MB 84.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 79.69MB / 237.08MB 89.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 82.84MB / 237.08MB 94.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 96.47MB / 237.08MB 95.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 110.10MB / 237.08MB 95.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 125.83MB / 237.08MB 96.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 138.41MB / 237.08MB 96.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 154.17MB / 237.08MB 97.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 158.33MB / 237.08MB 102.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 159.38MB / 237.08MB 107.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 160.43MB / 237.08MB 112.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 162.53MB / 237.08MB 117.9s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 163.58MB / 237.08MB 123.0s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 164.63MB / 237.08MB 128.1s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 164.63MB / 237.08MB 133.2s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 166.72MB / 237.08MB 138.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 169.87MB / 237.08MB 143.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 170.92MB / 237.08MB 148.5s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 173.02MB / 237.08MB 153.6s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 175.11MB / 237.08MB 158.7s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 177.21MB / 237.08MB 163.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 198.18MB / 237.08MB 165.3s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 211.81MB / 237.08MB 165.8s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 225.44MB / 237.08MB 166.4s
#7 sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 237.08MB / 237.08MB 166.8s done
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f
#7 extracting sha256:604add184d03d4cf6e2ff1c4b9013b265eb9c11570afe28ce8f9dc417b98ea3f 6.3s done
#7 DONE 174.3s
#7 docker-image://ghcr.io/railwayapp/railpack-builder:latest
#7 extracting sha256:df614908d6aba31e983953b17fd48496d27425529b3947c3d5583c4cc9c15c9a 0.0s done
#7 extracting sha256:193926ad1d06489b7487e8ac4ae2d0874e6ff05cf65d874d2af508830fc03def done
#7 DONE 174.3s
#14 mkdir /etc/mise
#14 DONE 1.6s
#15 create mise config
#15 DONE 0.0s
#16 install mise packages: bun, node
#16 0.084 mise by @jdx – installing 2 tools
#16 3.084 mise █████████░░░░░░░ 0/2 · 3.0s
#16 3.084 bun@1.4.4 downloading 2.3s 51.8/51.8 MB · 25.5 MB/s
#16 3.084 node@26.13.0 downloading 2.3s 41.8/62.9 MB · 18.8 MB/s
#16 3.792 mise bun@1.4.4 1.4.4
#16 3.806 mise ✓ bun@1.4.4 3.1s bun-linux-x64.zip
#16 5.420 mise node@26.13.0 v26.13.0
#16 5.580 mise node@26.13.0 11.20.0
#16 5.606 mise ✓ node@26.13.0 4.9s node-v26.13.0-linux-x64.tar.gz
#16 5.606 mise ████████████████ 2/2 · installed 2 tools in 5.5s
#16 DONE 6.2s
#17 copy / /app
#17 DONE 0.6s
#18 mkdir -p /app/node_modules/.cache
#18 DONE 0.1s
#19 bun install --frozen-lockfile
#19 0.105 bun install v1.4.4 (38afee6c8)
#19 ...
#20 copy /mise/shims
#20 DONE 0.1s
#21 copy /mise/installs
#21 DONE 5.6s
#19 bun install --frozen-lockfile
#19 ...
#22 copy /usr/local/bin/mise
#22 DONE 3.0s
#19 bun install --frozen-lockfile
#19 ...
#23 copy /etc/mise/config.toml
#23 DONE 0.1s
#24 copy /root/.local/state/mise
#24 DONE 0.1s
#19 bun install --frozen-lockfile
#19 14.66
#19 14.66 $ prisma generate || true
#19 16.63 Prisma schema loaded from prisma/schema.prisma
#19 17.61
#19 17.61 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 492ms
#19 17.61
#19 17.61 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#19 17.61
#19 17.61 Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate
#19 17.61
#19 17.74
#19 17.74 + @tailwindcss/postcss@4.1.18
#19 17.74 + @types/react@19.2.8
#19 17.74 + @types/react-dom@19.2.3
#19 17.74 + bun-types@1.3.6
#19 17.74 + eslint@9.39.2
#19 17.74 + eslint-config-next@16.1.3
#19 17.74 + tailwindcss@4.1.18
#19 17.74 + tw-animate-css@1.4.0
#19 17.74 + typescript@5.9.3
#19 17.74 + @dnd-kit/core@6.3.1
#19 17.74 + @dnd-kit/sortable@10.0.0
#19 17.74 + @dnd-kit/utilities@3.2.2
#19 17.74 + @hookform/resolvers@5.2.2
#19 17.74 + @hugeicons/core-free-icons@4.3.5
#19 17.74 + @hugeicons/react@1.1.10
#19 17.74 + @mdxeditor/editor@3.52.3
#19 17.74 + @prisma/client@6.19.2
#19 17.74 + @radix-ui/react-accordion@1.2.12
#19 17.74 + @radix-ui/react-alert-dialog@1.1.15
#19 17.74 + @radix-ui/react-aspect-ratio@1.1.8
#19 17.74 + @radix-ui/react-avatar@1.1.11
#19 17.74 + @radix-ui/react-checkbox@1.3.3
#19 17.74 + @radix-ui/react-collapsible@1.1.12
#19 17.74 + @radix-ui/react-context-menu@2.2.16
#19 17.74 + @radix-ui/react-dialog@1.1.15
#19 17.74 + @radix-ui/react-dropdown-menu@2.1.16
#19 17.74 + @radix-ui/react-hover-card@1.1.15
#19 17.74 + @radix-ui/react-label@2.1.8
#19 17.74 + @radix-ui/react-menubar@1.1.16
#19 17.74 + @radix-ui/react-navigation-menu@1.2.14
#19 17.74 + @radix-ui/react-popover@1.1.15
#19 17.74 + @radix-ui/react-progress@1.1.8
#19 17.74 + @radix-ui/react-radio-group@1.3.8
#19 17.74 + @radix-ui/react-scroll-area@1.2.10
#19 17.74 + @radix-ui/react-select@2.2.6
#19 17.74 + @radix-ui/react-separator@1.1.8
#19 17.74 + @radix-ui/react-slider@1.3.6
#19 17.74 + @radix-ui/react-slot@1.2.4
#19 17.74 + @radix-ui/react-switch@1.2.6
#19 17.74 + @radix-ui/react-tabs@1.1.13
#19 17.74 + @radix-ui/react-toast@1.2.15
#19 17.74 + @radix-ui/react-toggle@1.1.10
#19 17.74 + @radix-ui/react-toggle-group@1.1.11
#19 17.74 + @radix-ui/react-tooltip@1.2.8
#19 17.74 + @reactuses/core@6.1.9
#19 17.74 + @tanstack/react-query@5.90.19
#19 17.74 + @tanstack/react-table@8.21.3
#19 17.74 + class-variance-authority@0.7.1
#19 17.74 + clsx@2.1.1
#19 17.74 + cmdk@1.1.1
#19 17.74 + date-fns@4.1.0
#19 17.74 + embla-carousel-react@8.6.0
#19 17.74 + framer-motion@14.7.1
#19 17.74 + imapflow@2.9.1
#19 17.74 + input-otp@1.4.2
#19 17.74 + lucide-react@1.62.0
#19 17.74 + motion@12.43.0
#19 17.74 + next@16.1.3
#19 17.74 + next-auth@4.24.13
#19 17.74 + next-intl@4.7.0
#19 17.74 + next-themes@0.4.6
#19 17.74 + prisma@6.19.2
#19 17.74 + react@19.2.3
#19 17.74 + react-day-picker@9.13.0
#19 17.74 + react-dom@19.2.3
#19 17.74 + react-hook-form@7.71.1
#19 17.74 + react-markdown@10.1.0
#19 17.74 + react-resizable-panels@3.0.6
#19 17.74 + react-syntax-highlighter@15.6.6
#19 17.74 + recharts@2.15.4
#19 17.74 + sharp@0.34.5
#19 17.74 + sonner@2.0.7
#19 17.74 + tailwind-merge@3.7.0
#19 17.74 + tailwindcss-animate@1.0.7
#19 17.74 + uuid@11.1.0
#19 17.74 + vaul@1.1.2
#19 17.74 + z-ai-web-dev-sdk@0.0.18
#19 17.74 + zod@4.3.5
#19 17.74 + zustand@5.0.10
#19 17.74
#19 17.74 858 packages installed [17.64s]
#19 DONE 21.1s
#25 copy / /app
#25 DONE 5.7s
#26 bun run build
#26 2.808 $ prisma generate && next build --webpack && cp -r .next/static .next/standalone/.next/ && cp -r public .next/standalone/
#26 3.955 Prisma schema loaded from prisma/schema.prisma
#26 5.215 ┌─────────────────────────────────────────────────────────┐
#26 5.215 │ Update available 6.19.2 -> 8.0.0-rc.28 │
#26 5.215 │ │
#26 5.215 │ This is a major update - please follow the guide at │
#26 5.215 │ https://pris.ly/d/major-version-upgrade │
#26 5.215 │ │
#26 5.215 │ Run the following to update │
#26 5.215 │ npm i --save-dev prisma@latest │
#26 5.215 │ npm i @prisma/client@latest │
#26 5.215 └─────────────────────────────────────────────────────────┘
#26 5.215
#26 5.215 ✔ Generated Prisma Client (v6.19.2) to ./node_modules/@prisma/client in 764ms
#26 5.215
#26 5.215 Start by importing your Prisma Client (See: https://pris.ly/d/importing-client)
#26 5.215
#26 5.215 Tip: Want to turn off tips and other hints? https://pris.ly/tip-4-nohints
#26 5.215
#26 7.326 ⚠ You are using a non-standard "NODE_ENV" value in your environment. This creates inconsistencies in the project and is strongly advised against. Read more: https://nextjs.org/docs/messages/non-standard-node-env
#26 8.827 ▲ Next.js 16.1.3 (webpack)
#26 8.828
#26 8.884 Creating an optimized production build ...
#26 13.82 (node:57) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#26 13.82 (Use `node --trace-deprecation ...` to show where the warning was created)
#26 41.07 (node:92) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
#26 41.07 (Use `node --trace-deprecation ...` to show where the warning was created)
#26 58.46 ✓ Compiled successfully in 45s
#26 58.46 Skipping validation of types
#26 58.60 Collecting page data using 3 workers ...
#26 61.54 Generating static pages using 3 workers (0/4) ...
#26 61.94 Generating static pages using 3 workers (1/4)
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <A>. See https://react.dev/link/warning-keys for more information.
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 61.94 Each child in a list should have a unique "key" prop.
#26 61.94
#26 61.94 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <__next_viewport_boundary__>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <html>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <meta>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Each child in a list should have a unique "key" prop.
#26 62.25
#26 62.25 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
#26 62.25 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
#26 62.25 TypeError: Cannot read properties of null (reading 'useContext')
#26 62.25 at A (.next/server/chunks/6117.js:11:9382) {
#26 62.25 digest: '4089451167'
#26 62.25 }
#26 62.25 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
#26 62.39 ⨯ Next.js build worker exited with code: 1 and signal: null
#26 62.44 error: script "build" exited with code 1
#26 ERROR: process "bun run build" did not complete successfully: exit code: 1
------
> bun run build:
62.25
62.25 Check the top-level render call using <head>. See https://react.dev/link/warning-keys for more information.
62.25 Error occurred prerendering page "/_global-error". Read more: https://nextjs.org/docs/messages/prerender-error
62.25 TypeError: Cannot read properties of null (reading 'useContext')
62.25 at A (.next/server/chunks/6117.js:11:9382) {
62.25 digest: '4089451167'
62.25 }
62.25 Export encountered an error on /_global-error/page: /_global-error, exiting the build.
62.39 ⨯ Next.js build worker exited with code: 1 and signal: null
62.44 error: script "build" exited with code 1
------
ERROR: failed to build: failed to solve: process "bun run build" did not complete successfully: exit code: 1
❌ Railpack build failed
railpack-dfm-aos-lgbcnc-2Y1SV3 removed
Error occurred ❌, check the logs for details.