Applies prisma/migrations/*/migration.sql on first container boot via a
sourced docker-entrypoint-initdb.d script, so a fresh container matches a
`prisma migrate deploy` run without needing shadow-database privileges.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Verified exact file-type v22 magic-byte detection for all 5 formats against
real fixture buffers (no normalizeFormat aliases needed), and simplified the
converter's resolution-scaling gate to match audio.js's validation-boundary
pattern (app.js range-checks, converter trusts the value).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every other family (images, documents, fonts, ebooks) had a showcase
pair in the marquee; archives was missing one after the archive
conversion feature landed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Also adds a --color-family-archives CSS variable (light + dark) that
the plan didn't call out explicitly but is needed for the new family
tile/icon to render with a color instead of falling back silently.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Also fixes a third double-extension bug the plan missed: app.js derived
each job's uuid via path.basename(file.filename, path.extname(...)),
which only strips the last dot segment. For a compound extension like
tar.gz this left "<uuid>.tar" as the "uuid", overflowing the uuid
column (Char(36)) and crashing the request. Replaced with
stripExtension(). Also bumped rateLimitMaxJobs in jobs.test.js's config
override — the file's cumulative POST /api/jobs calls across all tests
now exceeds the production default (20/window) once the archive tests
are included, causing spurious connection resets independent of any
real bug.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
archiver v8 (installed) uses a class-based API (`ZipArchive`) rather than
the factory-function API most examples online still describe — adjusted
createZip() to match after the first test run surfaced the mismatch.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets users drop an uploaded file from the UI list before or after
conversion, without cancelling anything server-side.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebuild the visual identity from the actual Ombrora mark (violet/cyan aurora
blobs) instead of the generic blue/amber scheme, add Bricolage Grotesque and
IBM Plex Mono for display and code-like text, and give the hero an animated
aurora backdrop, gradient headline, and a format-pair marquee driven by the
real registered converters.
Rework the file config form: target format and icon size are both chip
groups now instead of a native select, and quality/compression sliders get a
gradient-filled track, custom thumb, and a mono value pill to match. File
type icons are color-coded by family (images/documents/fonts/ebooks) and
reused across FileConfigCard, FileCard, and FormatsGrid.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The download button was showing the input file's size (carried over
client-side from upload) instead of the actual converted file's size.
It now reads outputSizeBytes from the polled job status once done.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers flag-icons for the language switcher, a shared header layout
across the choose/convert/download states, human-readable file sizes,
and restyled format/quality controls and download button.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Explains the react-router-dom resolution failure encountered deploying
the frontend redesign, and the fix (mirror frontend runtime deps into
root package.json) so it doesn't need re-discovering next time.
The o2switch nodevenv/Passenger setup only installs a single
package.json/node_modules (root), so npm install --prefix frontend
never actually populates frontend/node_modules there. Node's module
resolution walks up from frontend/src to the root node_modules, so
adding react-router-dom, react-i18next, i18next, and
@phosphor-icons/react to root's dependencies (react/react-dom were
already present) lets the production vite build resolve them without
needing a second node_modules tree.
Migrates the existing upload/format-select/quality/convert logic from
the old single-file App.jsx into a router shell (/ -> /fr//en/) with a
shared Layout (header, language switcher, dark-mode toggle, footer).
Tool logic itself is unchanged, only restyled into cards.
Part of the Ombrora Convert redesign (Task 2/5).
Foundation sub-project: merged homepage+tool page, FR/EN i18n via URL
prefix, dark mode, SEO basics, and reassurance elements backed by
actual backend guarantees (1h auto-delete, 100MB max, no account).