Commit Graph

34 Commits

Author SHA1 Message Date
davidherran e879016879 fix: pass locale explicitly to next-intl helpers (DYNAMIC_SERVER_USAGE)
Deploy to VPS / deploy (push) Has been cancelled
Production logs were spamming "DYNAMIC_SERVER_USAGE" errors and every
ISR-cached page (home, news, heritage, applications, news/[slug]) was
500-ing. Root cause: when force-dynamic was replaced with revalidate=60
last commit batch, the implicit locale-resolution path through
next-intl's getTranslations() / getLocale() / getMessages() became a
problem. Without an explicit locale arg, next-intl reads cookies()
under the hood — which trips Next.js's "dynamic API used inside a
static / ISR render" guard and aborts with DYNAMIC_SERVER_USAGE.

Fix: pass the locale (already known from the URL via params) every
time we call next-intl on the server.

CHANGES
- src/components/layout/Footer.tsx
  - Now accepts `locale` as a prop instead of awaiting getLocale()
  - getTranslations({ locale, namespace: "Footer" })
- src/app/[locale]/layout.tsx
  - Passes locale prop to <Footer locale={locale} />
  - getMessages({ locale }) instead of getMessages()
- src/components/sections/PatrizioLegacy.tsx
  - Accepts `locale` prop, passes it to getTranslations
- src/app/[locale]/page.tsx
  - Renders <PatrizioLegacy locale={locale} />
- src/app/[locale]/news/page.tsx (body)
  - getTranslations({ locale, namespace: "NewsHub" })
- src/app/[locale]/heritage/page.tsx (body)
  - getTranslations({ locale, namespace: "HeritagePage" })

The generateMetadata / generateStaticParams paths in news/[slug] and
heritage already passed locale correctly — only the page bodies and
shared components were leaking dynamic reads.

Net effect: all five ISR pages render statically again, the error spam
in `docker compose logs app` clears, and /en/applications/digital-print
loads its server component without falling through to the error boundary.
2026-05-04 16:53:20 -05:00
davidherran 3d066fa67e fix: error boundaries + defensive try/catch on dynamic pages
Deploy to VPS / deploy (push) Has been cancelled
The /en/applications/digital-print page was still 500-ing after the
previous fixes. Without an error boundary, Next.js shows a generic
"Internal Server Error" with no detail — making remote diagnosis
require a `docker compose logs` round-trip every time.

ERROR BOUNDARIES (visible diagnostics)
- src/app/global-error.tsx: catches errors that bubble past every
  route's error.tsx, including ones from the root layout. Renders
  its own <html>/<body>.
- src/app/[locale]/error.tsx: locale-scoped boundary so the NavBar
  and Footer keep rendering around the error UI. Shows the actual
  error message + digest in a code block — much faster to diagnose
  than a blank 500.

DEFENSIVE WRAPPING (every async + every transform)
- applications/[slug]/page.tsx
  - getApplicationImages: try/catch around fs ops
  - generateMetadata: full body wrapped, falls back to safe defaults
  - getLocalizedData call wrapped (returns rawData if it throws)
  - Cases query already had try/catch — adds same for the locale map
  - JSON-LD build wrapped, falls back to empty array (still renders)
  - Default fallbacks for title/description/category to avoid
    productSchema receiving undefined fields
- news/[slug]/page.tsx
  - prisma.newsArticle.findUnique now has try/catch
  - getLocalizedData wrapped
  - JSON-LD build wrapped, only rendered if non-empty
  - publishedAt / updatedAt fallback to new Date() to avoid
    "Invalid time value" from articleSchema's date conversion

The combination means: if the underlying bug is in any of the SEO
helpers, JSON-LD generation, or i18n merging, the page now degrades
gracefully and shows the actual error in the UI instead of 500-ing.
2026-05-04 16:45:37 -05:00
davidherran 62506f10b4 fix: strip internal container port from redirect URLs
Deploy to VPS / deploy (push) Has been cancelled
The site was redirecting / -> https://rf-flux.com:3000/en, where :3000
is the container's internal port (only "expose"d, not published) — so
the browser saw ERR_CONNECTION_REFUSED.

Root cause: when running behind Nginx in standalone mode, Next.js (via
next-intl in this case) can build absolute redirect URLs that leak the
container's internal PORT/HOSTNAME env into the Location header.

TWO LAYERS OF DEFENCE
1. Nginx (nginx/conf.d/flux.conf)
   - Adds X-Forwarded-Host + X-Forwarded-Port so the upstream knows
     the public port (443) and host
   - proxy_redirect rewrites any Location header that still slips
     through with :3000 back to the public https://$host

2. Middleware (src/proxy.ts)
   - sanitizeRedirectLocation() runs after handleI18nRouting and
     scrubs Location headers that point at internal hostnames (app /
     localhost / 0.0.0.0) or the container port :3000, replacing them
     with the public host derived from x-forwarded-host / host header.

Either layer alone would fix the immediate symptom; together they
also prevent the same class of bug from showing up in any future
redirect path.
2026-05-04 16:32:45 -05:00
davidherran 5abd3a02f6 fix: ship full prod node_modules to runner so prisma migrate deploy works
Deploy to VPS / deploy (push) Has been cancelled
The previous container restart loop ("Error: Cannot find module 'effect'")
happened because the runner stage cherry-picked only specific Prisma
subdirs (.prisma, @prisma, prisma) but missed transitive runtime deps
of the Prisma CLI — like @prisma/config's dep on `effect`.

Cherry-picking is fragile: any minor Prisma upgrade changes the
required dep set and the container stops booting.

Real fix: introduce a dedicated prod-deps stage that runs
`npm ci --omit=dev --include=optional` and ship the resulting
node_modules wholesale to the runner. Trade-off: the runner image
grows by ~200-300MB, gaining bullet-proof prod CLI execution in
exchange. Subsequent rebuilds are fully cached after the first run.

What changed in Dockerfile:
- New stage `prod-deps` produces a prod-only node_modules tree
- Runner stage drops the explicit @prisma/prisma/sharp/@img copies
  (they're already in prod-deps' node_modules)
- Still copies prisma/, prisma.config.ts, .prisma generated client,
  and Next.js standalone artefacts
- CMD unchanged: migrate deploy + server.js
2026-05-04 16:22:47 -05:00
davidherran 320c0862df fix: pin all sharp platform binaries so npm ci works on any host
Deploy to VPS / deploy (push) Has been cancelled
The previous attempts (--include=optional, then a separate npm install
fallback) failed because npm ci runs sharp's install script DURING
installation — and that script crashes ("Please add node-gyp to your
dependencies") before the next Dockerfile step gets to run.

Real fix: pin every sharp platform binary as an optionalDependency in
package.json. npm now records URL+hash for all of them in the lock
file regardless of which OS generated the lock. On any build host,
npm ci picks the matching binary via the os/cpu/libc filters in those
packages and silently skips the rest.

Pinned binaries (sharp 0.34.5):
- @img/sharp-linuxmusl-x64   (Alpine x64 — our VPS)
- @img/sharp-linuxmusl-arm64 (Alpine arm64)
- @img/sharp-linux-x64       (glibc x64)
- @img/sharp-linux-arm64     (glibc arm64)
- @img/sharp-darwin-arm64    (Apple Silicon dev)
- @img/sharp-darwin-x64      (Intel Mac dev)

Side benefit: simplifies the Dockerfile. Drops the secondary
`npm install --no-save --cpu=x64 --os=linux --libc=musl sharp` step
and the vips-dev system package (no source compilation needed when
the prebuilt binary is guaranteed present). The runner stage still
needs `vips` runtime, that stays.
2026-05-04 15:52:22 -05:00
davidherran 4f75943317 fix: force sharp Alpine binary download in Docker build
Deploy to VPS / deploy (push) Has been cancelled
Sharp 0.34 ships a separate prebuilt binary per platform tuple as
optionalDependencies (@img/sharp-linuxmusl-x64 for Alpine, -darwin-arm64
for Apple Silicon, etc).

The lock file only records the dev machine's platform binary. `npm ci`
is strict — it installs exactly what's locked and refuses to add
platform-specific entries that weren't there at lock time. Result on
the VPS Alpine x64 build:

  sharp: Attempting to build from source via node-gyp
  sharp: Please add node-gyp to your dependencies

Fix: after the strict `npm ci`, run a separate `npm install --no-save
--cpu=x64 --os=linux --libc=musl sharp`. This downloads the Alpine
binary into node_modules without modifying package.json or the lock,
so the dev's Mac install stays untouched on the next git pull.

This is the recommended pattern from sharp's own docs for cross-target
Docker builds: https://sharp.pixelplumbing.com/install#cross-platform
2026-05-04 15:43:30 -05:00
davidherran 89505c73cc fix: pin @swc/helpers explicitly so npm ci works on npm 10 (Alpine)
Deploy to VPS / deploy (push) Has been cancelled
The Docker build on the VPS failed because:
  npm error Missing: @swc/helpers@0.5.21 from lock file

Cause: Next.js 16.1.6 declares @swc/helpers both as a direct dep at
0.5.15 AND as a peer dep ">=0.5.17". npm 11 (my local) accepts the
0.5.15 install and considers the peer satisfied. npm 10.9.7 (the
Alpine container in the VPS) is stricter — it tries to resolve the
peer to its own version and demands 0.5.21, which our lock file
didn't have.

Fix:
- Add @swc/helpers ^0.5.17 as a direct dependency so both npm 10 and
  npm 11 pick the same up-to-date version (resolved to 0.5.21).
- Regenerate package-lock.json from a clean install so it matches.

`npm ci` now succeeds in the docker-compose build.
2026-05-04 15:35:20 -05:00
davidherran f8606a45ff feat: branding asset serving + footer email/phone fields
Deploy to VPS / deploy (push) Has been cancelled
Two changes that together make Site Settings actually work end-to-end.

BRANDING ASSET SERVING (the broken thumbnails fix)
The favicon/logo previews were broken because uploaded files in
/public/branding had no path to reach the browser:
  1. The folder wasn't mounted into the app container, so uploads
     vanished on next deploy
  2. Nginx had no location block, so /branding/foo.png returned 404
     (everything not in cases/applications/news/parts/footage was a
     proxy_pass to Next.js, which doesn't serve from /public/branding
     in standalone mode)

Fix:
- docker-compose.yml: ./public/branding mounted to /app/public/branding
  (write side) AND /srv/branding (read-only side for Nginx)
- nginx/conf.d/flux.conf: new "location /branding/" block, same
  cache strategy as the other asset locations (max-age=300, must-revalidate)

FOOTER EMAIL + PHONE (David's request)
- siteSettingsTypes.ts: hqEmail and hqPhone fields added to FooterSettings,
  pre-filled with sales@lethepowerflux.com and +39 0424 287 492
- Footer.tsx: clickable mailto: and tel: links with Mail / Phone icons
  shown right under the HQ address. Hidden when fields are empty so the
  layout stays clean for editors who want to suppress contact info.
- /hq-command/dashboard/settings: new "Headquarters contact" group in
  the Footer tab with the two fields (auto-translate ignores them, since
  emails and phone numbers don't need translation).

DEPLOY (David)
  cd /opt/flux-srl
  mkdir -p public/branding   # one-time, creates the folder if missing
  git pull
  docker compose up -d --build app
  docker compose exec nginx nginx -t
  docker compose exec nginx nginx -s reload
2026-05-04 15:24:06 -05:00
davidherran 01a84edee9 fix: prisma migrate now runs at container startup + dotenv optional
Deploy to VPS / deploy (push) Has been cancelled
Two related fixes for the deploy pipeline so DB schema changes never
again leave the site half-deployed.

PRISMA CONFIG (prisma.config.ts)
- "import 'dotenv/config'" was hard-required, but dotenv isn't installed
  in the production runtime image (env vars come from docker-compose).
- Wrapped in try/catch so it loads .env locally and silently no-ops in
  the container — `prisma migrate deploy` works in both environments.

DOCKERFILE
- Copies node_modules/prisma + prisma.config.ts to the runner stage so
  the CLI is available at runtime, not just at build.
- New CMD runs `prisma migrate deploy` before booting the server.
  Idempotent — already-applied migrations are skipped. If the DB is
  unreachable, the container exits and docker-compose retries.
- This means: from now on, `git pull && docker compose up -d --build app`
  is the entire deploy. No more "did you remember to run migrations?".

DEFENSIVE TRY/CATCH (applications/[slug]/page.tsx)
- prisma.application.findUnique and prisma.globalNode.findMany now have
  try/catch with logged errors. A transient DB hiccup or missing
  Application slug now degrades gracefully (renders "not found" or empty
  cases wall) instead of triggering a 500 Internal Server Error.

DEPLOY (David, this is the recovery sequence on the VPS)
  cd /opt/flux-srl
  git pull
  docker compose up -d --build app
  # The container will run pending migrations on its own.
  # No need to run `prisma migrate deploy` manually anymore.
2026-05-04 15:04:35 -05:00
davidherran a199891a3c feat: FluxAI multi-step autonomy + rate limiting + image pipeline
Deploy to VPS / deploy (push) Has been cancelled
Two production-grade hardening additions and one cost optimisation.

FLUXAI AUTONOMY RESTORED (api/chat)
- Brings back the multi-step agentic flow that the system prompt was
  always designed for. The "temporarily removed maxSteps" comment is
  gone — replaced with the AI SDK 6 equivalent stopWhen: stepCountIs(5).
- Cap at 5 chained tool calls per turn bounds latency + LLM cost.
- maxDuration raised 30s → 60s to absorb tool-chain runs.
- Result: one user prompt now triggers, e.g. search_installations →
  energy_savings_calculator → show_case_study → schedule_consultation
  in a single turn — exactly the SPIN methodology in the prompt.

RATE LIMITING (src/lib/rateLimit.ts + api/chat)
- Token-bucket per IP: 30 messages burst, sustained 30/minute. Trips
  to 429 with Retry-After + X-RateLimit-Remaining headers when abused.
- IP extracted from x-forwarded-for (Nginx already passes this).
- In-memory Map with 10-min GC of stale buckets — no Redis dep.
  If we scale to multiple replicas later, swap the Map for Upstash.
- Protects the OpenAI quota from someone hammering the chat endpoint.

IMAGE PIPELINE (src/lib/imageOptimizer.ts)
- sharp-based optimizer: auto-orient (EXIF), cap at 2560px long side,
  re-encode WebP@85, content-hash filename. Re-uploads with same
  content reuse the same hash; new content gets a new URL — perfect
  cache invalidation without header tricks.
- Opt-in via optimize=1 form/query param on /api/assets POST.
- Hero CMS and Site Settings uploads turn it on automatically (those
  are user-facing brand assets where compression matters most).
- App/news/parts uploads remain untouched (editors may be uploading
  CAD drawings, datasheets, etc. that shouldn't be transcoded).
- Falls back gracefully to a no-op for unsupported formats (SVG, GIF,
  videos, anything sharp can't decode) so it never breaks an upload.

DOCKERFILE
- Adds vips/vips-dev for sharp on Alpine + --include=optional so the
  @img/sharp-linuxmusl-x64 prebuilt is downloaded
- Explicitly copies node_modules/sharp + node_modules/@img to the
  runner stage (Next.js trace can miss conditional deps).

NO DB SCHEMA CHANGES.
2026-05-04 14:48:37 -05:00
davidherran 09e6d0c7cf seo: dynamic sitemap + robots + per-page metadata + JSON-LD
Brings the site up to enterprise SEO standards. Google now gets a complete
machine-readable map of the content, with multilingual hreflang tags,
structured data for the knowledge panel, and rich Open Graph cards on
LinkedIn / WhatsApp / Twitter.

NEW
- src/app/sitemap.ts: dynamic sitemap.xml from Prisma. Emits 5 locales x
  every active application + every active news article, with hreflang
  alternates linking each translation. Hourly revalidation.
- src/app/robots.ts: robots.txt blocks /hq-command/, /api/, /parts (B2B
  auth-gated), points crawlers at the sitemap.
- src/lib/seo.ts: helpers for canonical URLs, hreflang alternates, and
  JSON-LD schemas (Organization, WebSite, Article, Product, BreadcrumbList).
- src/components/seo/JsonLd.tsx: server component that emits one
  application/ld+json script tag per page.

PER-PAGE generateMetadata
- Home: localized titles + descriptions in EN/IT/VEC/ES/DE
- News hub: title built from translations, hreflang tags
- News article: title/description from DB, OG image = cover, type=article,
  publishedTime + modifiedTime for date freshness signals
- Applications: title/description from DB, type=product, hero image
- Heritage: localized title/description

JSON-LD STRUCTURED DATA
- Site-wide (in root layout): Organization (with HQ address, founder,
  contact, social profiles) + WebSite — drives Google knowledge panel
- Article pages: Article schema with publisher/datePublished/dateModified
  — required for Google News / Discover eligibility
- Application pages: Product schema (FLUX brand, RF Industrial category)
  + BreadcrumbList — drives rich-snippet breadcrumb in search results

NOTES
- Open Graph metadataBase set from NEXT_PUBLIC_APP_URL so absolute URLs
  for OG images are correct (LinkedIn previews require absolute paths)
- All pages have canonical URLs to prevent duplicate-content penalties
- /parts already has noindex meta (B2B portal) — also blocked in robots
- No DB schema changes. Pure additions to /src/lib and /src/app.
2026-05-04 14:42:43 -05:00
davidherran f931ae281c i18n: preserve technical industry terms across all locales
Deploy to VPS / deploy (push) Has been cancelled
Some technical terms were being translated literally and reading awkwardly
to industrial buyers — fixed across IT, ES, VEC, DE so they match the
English source and industry convention.

PRESERVED IN ENGLISH (industry-standard, never translate)
- "Solid-State RF" — was "RF a Stato Solido" / "RF de Estado Sólido" /
  "RF a Stato Sołido" / "Solid-State-RF"
- "Microwave Systems" — was "Sistemi a Microonde" / "Sistemas de
  Microondas" / "Mikrowellensysteme" / "Sistemi Microwave"
- "Radio Frequency (RF)" — was "Radiofrequenza" / "Radiofrecuencia" /
  "Radiofrequensa" / "Hochfrequenztechnologie" (kept as the technical
  proper noun, with the RF acronym in parentheses for first reference)
- "Pulse Wave" — was "onde pulsate" / "ondas pulsadas" / "onde pulsà" /
  "Pulswellen-Technologie"

Files: messages/it.json, messages/es.json, messages/vec.json,
messages/de.json. messages/en.json unchanged. JSON syntax validated.
2026-05-04 13:14:20 -05:00
davidherran b9a744bdbc feat: site settings CMS — favicon, logo, footer, social, OG image
Adds a full settings dashboard at /hq-command/dashboard/settings so the
client can update favicon, logos, footer text, social links and OG image
without code changes — wired into the SiteSetting model from the previous
commit.

NEW
- src/lib/siteSettingsTypes.ts: pure types + defaults (client-safe import)
- src/lib/siteSettings.ts: server-only loader using the SiteSetting model
- /api/assets gains a "branding" flat scope that writes to /public/branding
- /hq-command/dashboard/settings/{actions.ts, page.tsx} with three tabs:
    1. Branding — favicon, Apple touch icon, main logo, email logo, OG
       image, theme color. Each field has helper text with recommended
       size/format and live preview.
    2. Footer — CTA banner, HQ address, legal links. Optional one-click
       AI translation to IT, VEC, ES, DE.
    3. Social — LinkedIn, Instagram, YouTube, contact email.

WIRED INTO LAYOUT
- src/app/[locale]/layout.tsx now uses generateMetadata + generateViewport
  to pull favicon, OG image and theme color dynamically. Adds Twitter
  Card metadata. Falls back to the default flux-logo when SiteSetting
  table is empty.
- src/components/layout/Footer.tsx reads CTA/HQ/legal copy from DB,
  supports per-locale overrides via translationsJson, and renders social
  icons (LinkedIn / Instagram / YouTube / Mail) only for filled fields.

UX FOR THE EDITOR (David's "12-year-old test")
- Drop-zone uploaders next to URL inputs — paste-or-upload either way
- Live image previews next to every branding field
- "Saved — live in 60 seconds" inline confirmation, no extra modals
- Recommended sizes spelled out next to each field (e.g. "PNG, square,
  minimum 512×512" for favicon)
- Tooltip explaining why each image is needed

NO SCHEMA CHANGES — uses the SiteSetting table created in the previous
commit. Existing rows untouched.
2026-05-04 12:47:10 -05:00
davidherran b9201a437c feat: hero carousel CMS + responsive mobile/iPad fix + flat-scope assets
Replaces the filesystem-scan hero (fs.readdirSync of /public/footage/main)
with a fully CMS-driven HeroSlide model. Editors can now drag-drop reorder,
toggle slides on/off, set focal points for proper mobile cropping, and
auto-translate per-slide captions.

NEW SCHEMA (additive — does not touch existing tables)
- HeroSlide: mediaUrl, mediaType, altText, order, isActive, focalPointX,
  focalPointY, translationsJson, timestamps
- SiteSetting: key-value JSON store for site-wide config (favicon, logo,
  footer, OG image) — wired up in next commit
- Migration 20260504120000_add_hero_slides_and_site_settings/migration.sql
  uses CREATE TABLE IF NOT EXISTS, additive only

HERO REEL REFACTOR (Bug #4 — responsive mobile/iPad)
- Switches from `images: string[]` to `slides: HeroSlideData[]` while
  keeping a backwards-compat path so legacy callers still work
- w-screen → w-full max-w-[100vw] (no horizontal scroll on iOS)
- h-[100vh] → h-[100svh] so iOS Safari URL bar doesn't push content
- Reduces title font sizes on small viewports (text-3xl → text-4xl
  → text-5xl → text-[5.5rem]) so the headline stays inside the canvas
- objectPosition driven by focal-point fields per slide
- Native <video> support for video slides

HQ COMMAND — /hq-command/dashboard/hero
- Drag-drop reorder, click-to-set-focal-point, inline alt-text editing
- Auto-save with "Saving…" / "Saved ✓" indicators
- Per-slide caption overrides (title, subtitle, descriptions)
- Optional one-click AI translation to IT, VEC, ES, DE
- Drop-zone uploader → /api/assets (scope=footage, flat folder)

API — /api/assets
- New flat scopes: "footage" (writes to /public/footage/main) and
  "branding" (writes to /public/branding) — slug-less for site-wide assets
- New buildPublicUrl helper centralises the URL convention
- Revalidate helper expanded with branding + settings scopes

HOME PAGE
- Reads hero slides from DB first; falls back to filesystem scan when
  HeroSlide table is empty (so production keeps working immediately
  after migration runs but before the editor populates rows)

DEPLOY NOTES
- After git pull on VPS, run the migration ONCE:
    docker compose exec app npx prisma migrate deploy
  Then:
    docker compose up -d --build app
  Existing data (AdminUser w/ 2FA, ClientUser, GlobalNode, Application,
  TimelineEvent, NewsArticle, HeritageSection, SparePart, OperationsSignal,
  NotificationRoute, PageContent) is NOT touched. Migration only creates
  two new tables.
2026-05-04 09:34:49 -05:00
davidherran 6e46808c27 fix: instant CMS uploads + heritage dark/light + ISR caching
Eliminates the need to run "docker compose build" after uploading
images via HQ Command. Heritage page now respects light/dark mode.

CACHE INVALIDATION
- New helper src/lib/revalidate.ts called from /api/assets and
  /api/public-upload after every upload, delete, folder create
- Pages switch from force-dynamic to ISR with revalidate=60
  (regenerated on demand whenever content changes, plus 60s safety)
- Nginx now sends "max-age=300, must-revalidate" instead of "expires 30d"
  on /cases/, /applications/, /news/, /parts/, /footage/, /operations-inbox/
  so browsers revalidate via If-Modified-Since (304s on unchanged files)
- Next.js Image Optimizer aligned with same TTL via minimumCacheTTL=300
  and adds /_next/image location block in Nginx for correct headers

HERITAGE DARK/LIGHT FIX (Bug #8)
- Replaces hardcoded #0A0A0C / #00F0FF / text-white with proper
  light + dark variants throughout markdown renderer (tables, lists,
  headings, blockquotes, paragraphs, images)
- Hero section, navigation pill, and CMS-driven sections now switch
  with the global theme toggle

SECURITY HARDENING
- Server actions bodySizeLimit reduced from 500MB to 50MB
  (large uploads still go through /api/assets which uses Nginx 500MB cap)

DEPLOY NOTES
- Run on VPS:
    git pull
    docker compose up -d --build app
    docker compose exec nginx nginx -s reload
- No DB schema changes in this commit. Existing 2FA users / data untouched.
2026-05-04 09:27:46 -05:00
davidherran 226b721721 fixes Network CoverImage3
Deploy to VPS / deploy (push) Has been cancelled
2026-04-21 11:06:40 -05:00
davidherran 8556ef78f4 fixes Network CoverImage2
Deploy to VPS / deploy (push) Has been cancelled
2026-04-21 10:47:58 -05:00
davidherran 64f23d833c fixes Network CoverImage
Deploy to VPS / deploy (push) Has been cancelled
2026-04-21 09:52:54 -05:00
davidherran 7ae5685ca9 fixes News
Deploy to VPS / deploy (push) Has been cancelled
2026-04-21 09:44:26 -05:00
davidherran da5a2ce2a2 fixes ApplicationIMG2
Deploy to VPS / deploy (push) Has been cancelled
2026-04-17 16:28:56 -05:00
davidherran 7fe1863c68 fixes ApplicationIMG
Deploy to VPS / deploy (push) Has been cancelled
2026-04-17 14:37:51 -05:00
davidherran 603ef51637 fixes Application nodeSlug
Deploy to VPS / deploy (push) Has been cancelled
2026-04-16 15:50:43 -05:00
davidherran 9d0ec57d7c fixes Markdown & Apex Globe
Deploy to VPS / deploy (push) Has been cancelled
2026-04-16 12:45:48 -05:00
davidherran 21d0f9ee1c fixes Markdown
Deploy to VPS / deploy (push) Has been cancelled
2026-04-16 10:29:20 -05:00
davidherran 69eb449da8 chore: untrack public assets, manage them outside git
Deploy to VPS / deploy (push) Has been cancelled
2026-04-16 13:18:26 +00:00
davidherran 86ef0e2d75 agregar idiomas a parts
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 12:47:26 -05:00
davidherran 20976432c9 fix: asset manager no longer closes edit modal on select
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 12:14:40 -05:00
davidherran c5b78c539e fix: nginx serves uploaded assets directly, docker volumes for all public dirs
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 17:07:49 +00:00
davidherran 80bb1962b2 fix: bodySizeLimit type
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 11:28:56 -05:00
davidherran cff3dc44be fix: upload limits and timeouts
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 11:26:46 -05:00
davidherran 3c20ce5c37 fix: upload limit 500MB, mount all public dirs in docker
Deploy to VPS / deploy (push) Has been cancelled
2026-04-08 15:56:56 +00:00
davidherran 0118774e31 production: docker fixes, nginx SSL config, generateStaticParams fallback
Deploy to VPS / deploy (push) Has been cancelled
2026-04-01 16:57:22 +00:00
davidherran fc24313f15 production: docker + nginx config for rf-flux.com
Deploy to VPS / deploy (push) Has been cancelled
2026-03-20 13:46:05 -05:00
davidherran b275b19f08 Initial commit from Create Next App 2026-02-22 11:45:37 -05:00