Commit Graph
152 Commits
Author SHA1 Message Date
anthony 6fc3386965 fix(seo): pass lang as a prop to Header/LanguageSwitcher instead of useParams
Since the vite-react-ssg migration replaced the dynamic /:lang route param
with literal /fr and /en routes, useParams().lang always returned undefined
here, breaking the header brand link (linked to /undefined/) and silently
breaking the language switcher (always resolved otherLang to 'fr').
2026-08-02 10:58:23 +02:00
anthony 74c676df9f specs 2026-08-02 10:57:41 +02:00
anthony 3a9836d58b feat(seo): add video and audio conversion pages 2026-08-02 10:39:08 +02:00
anthony 04b792c454 feat(seo): add remaining document conversion pages 2026-08-02 10:36:59 +02:00
anthony 0e19f92cda feat(seo): add remaining image, HEIC, and ICO conversion pages 2026-08-02 10:35:11 +02:00
anthony e6ab78de29 feat(seo): add conversion-page scaffolding with 2 seed pairs (jpg-to-png, pdf-to-docx) 2026-08-02 10:32:53 +02:00
anthony 3b53d82b3d feat(seo): migrate to build-time prerendering with vite-react-ssg
Fixes SeoHead (title/canonical/hreflang/JSON-LD) to render during SSR via
vite-react-ssg's Head component instead of a client-only useEffect, so
crawlers see real tags without executing JS. Also fixes an SSR crash in
useTheme (localStorage access with no window during server render) and
removes now-duplicated static meta tags from index.html.
2026-08-02 10:30:26 +02:00
anthony 8dcc5f3405 chore(frontend): downgrade react-router-dom to v6 for vite-react-ssg compatibility 2026-08-02 10:24:43 +02:00
anthony c07663aa7b feat(seo): return a real 404 status for unmatched routes 2026-08-02 10:23:07 +02:00
anthony b2636e20cf feat(seo): redirect / to /fr/ or /en/ server-side based on Accept-Language 2026-08-02 10:21:38 +02:00
anthony 5ff8a865e8 feat(seo): add compression, cache-control headers, configurable frontend dist path 2026-08-02 10:20:22 +02:00
anthony 26433fa9c7 docs: add implementation plan for SEO fixes and prerendering migration
11 tasks: Express fixes (compression/cache/redirect/404), react-router-dom
v6 downgrade (required for vite-react-ssg compatibility, verified via
dry-run), vite-react-ssg prerendering migration, and 30 curated
conversion-pair landing pages with real fr/en content.
2026-08-02 10:13:28 +02:00
anthony 9d30ff4c74 docs: add design spec for SEO fixes and prerendering migration
Covers server-side redirects/404, compression/cache headers, dynamic
sitemap, vite-react-ssg prerendering with react-helmet-async, and 30
curated conversion-pair landing pages.
2026-08-02 09:51:40 +02:00
anthonyandClaude Sonnet 5 afb0fed650 feat(video): add video format family, resolution control, and marquee pair
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-02 09:07:23 +02:00
anthonyandClaude Sonnet 5 770d2c9bdc feat(infra): add docker-compose for local MariaDB with Prisma schema init
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>
2026-08-02 09:05:36 +02:00
anthonyandClaude Sonnet 5 457913d8d4 feat(video): wire video converters, resolution validation, and timeout into app.js/worker.js
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 22:01:58 +02:00
anthonyandClaude Sonnet 5 9c1f857398 feat(video): add MIME types for mp4/webm/mov/avi/mkv
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:59:06 +02:00
anthonyandClaude Sonnet 5 913dbac691 feat(video): add ffmpeg-backed video converter for mp4/webm/mov/avi/mkv
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:58:23 +02:00
anthonyandClaude Sonnet 5 886c2e8539 feat(video): add configurable VIDEO_JOB_TIMEOUT_MS
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:57:37 +02:00
anthonyandClaude Sonnet 5 a92556808a docs(video): add implementation plan for video conversion feature
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 21:53:56 +02:00
anthonyandClaude Sonnet 5 728247a2cf docs(video): refine spec with verified file-type detection and simplified converter
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>
2026-08-01 21:51:50 +02:00
anthonyandClaude Sonnet 5 69b3de8031 docs(video): add design spec for video conversion feature
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 15:23:49 +02:00
anthony 3775d34a22 feat(audio): add bitrate chip control, default bitrates, and marquee pair 2026-08-01 14:22:40 +02:00
anthony 3d62d2983b feat(audio): recognize the audio family in the frontend formats grid 2026-08-01 14:19:39 +02:00
anthony 433ff3b726 feat(audio): add MIME types for mp3/wav/ogg/flac/aac/m4a 2026-08-01 14:17:25 +02:00
anthony 050ea5ba64 feat(audio): wire audio converters and bitrate validation into app.js/worker.js 2026-08-01 14:15:13 +02:00
anthony 05be353664 feat(audio): add ffmpeg-backed audio converter for mp3/wav/ogg/flac/aac/m4a 2026-08-01 14:13:09 +02:00
anthony 13d095aa4c docs: add audio conversion implementation plan 2026-08-01 13:41:00 +02:00
anthony aa5383d7f0 docs: fix m4a mime type and document exact file-type detection bytes 2026-08-01 13:38:48 +02:00
anthony a23ccf465c docs: add audio conversion design spec 2026-08-01 13:34:44 +02:00
anthonyandClaude Sonnet 5 74db0ecfcc feat(frontend): add archive pair to the homepage format marquee
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>
2026-08-01 13:09:38 +02:00
anthonyandClaude Sonnet 5 48c70254c1 feat(frontend): add archive format family, compression control, and fixed double-extension parsing
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>
2026-08-01 13:03:30 +02:00
anthonyandClaude Sonnet 5 ef6de6b583 feat(archive): wire archive converters, validation, and extension parsing into app.js/worker.js
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>
2026-08-01 13:00:01 +02:00
anthonyandClaude Sonnet 5 a8cdb06d5c feat(archive): add MIME types and compound-extension aliases for archive formats
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:55:56 +02:00
anthonyandClaude Sonnet 5 ceddeddf3e feat(archive): add rar extraction support
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:55:10 +02:00
anthonyandClaude Sonnet 5 a66143d312 feat(archive): add 7z and tar.7z converters
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:53:36 +02:00
anthonyandClaude Sonnet 5 a76b10a43f feat(archive): add tar.bz2 converter via 7za
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:52:29 +02:00
anthonyandClaude Sonnet 5 c9251e66e2 feat(archive): add tar and tar.gz converters
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:51:34 +02:00
anthonyandClaude Sonnet 5 d68694ead8 feat(archive): add zip converter with compression level and zip-slip protection
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>
2026-08-01 12:49:46 +02:00
anthonyandClaude Sonnet 5 031df9a999 feat(archive): add double-extension-aware filename parsing helper
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 12:47:27 +02:00
anthonyandClaude Sonnet 5 a7a91a7a2e feat(frontend): add remove button to pending and submitted file cards
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>
2026-07-31 16:47:18 +02:00
anthonyandClaude Sonnet 5 987af80286 feat(frontend): redesign homepage and file config form with aurora palette
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>
2026-07-31 16:34:13 +02:00
anthonyandClaude Sonnet 5 023a96e5d8 feat(frontend): show destination format badge, fix download size to reflect converted output
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>
2026-07-31 16:14:44 +02:00
anthonyandClaude Sonnet 5 db3e73860b feat(api): expose outputSizeBytes on job status
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 16:14:38 +02:00
anthonyandClaude Sonnet 5 89749d8c20 fix(frontend): show file size in the download button label
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 16:10:29 +02:00
anthonyandClaude Sonnet 5 a647bee507 feat(frontend): thread file size from upload through to the download card
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 16:04:01 +02:00
anthonyandClaude Sonnet 5 f1f7a0162d feat(frontend): add icon/size header, spinner, and styled download button to FileCard
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 16:02:06 +02:00
anthonyandClaude Sonnet 5 994d70aa62 feat(frontend): restyle format picker and add file size to the config card
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 16:01:37 +02:00
anthonyandClaude Sonnet 5 7c58e50c11 feat(frontend): use flag icons in the language switcher
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 15:59:39 +02:00
anthonyandClaude Sonnet 5 f5958586b7 feat(frontend): add formatBytes util for human-readable file sizes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 15:53:03 +02:00