Fahem General Trading
- Client
- Fahem General Trading
- Industry
- Coffee export & agriculture
- Year
- 2025
A coffee exporter’s corporate site built entirely on editable content: origins, farms, traceability steps, export markets, ventures and milestones are all database rows, not hardcoded pages.
Visit the site
14
Content types the client edits without a developer
0
Hardcoded pages to update at harvest
1
Traceability chain, shown as ordered stages
What it covers
- Content-modelled corporate site
- Origin, farm & traceability pages
- Export market & partner directory
- Ventures & company timeline
- Enquiry inbox & email notification
- Roles & permissions
What a coffee exporter's website is for
An Ethiopian coffee exporter is not selling to walk-in customers. The audience is a small number of foreign buyers who are deciding whether to trust a supplier they have never met, from a country they may never visit, with a container of something whose quality they cannot verify until it lands.
That makes the website an act of proof, not persuasion. The build is organised around the specific things a buyer checks.
The content model
Every one of these is a table the client edits:
- Coffee regions and sub-regions: Jimma, Limu, and the growing areas beneath them, each with its own profile.
- Coffee products: grades and lots, tied to where they came from.
- Farms: the actual sources, with their own pages.
- Traceability steps: the chain from cherry to container, laid out as ordered stages. This is the section that answers the buyer's real question.
- Export markets: where the company already ships, which is itself a credential.
- Ventures: the group's other businesses.
- Milestones: the company timeline.
- Value propositions, partners, FAQs, gallery and testimonials.
Alongside those: page heroes and site settings, so the headline image and the contact details on any page are content rather than code.
Why it was built this way
The alternative (a designer's static pages) would have been faster to ship and wrong within a season. Harvests change, grades change, markets are added. A site that cannot keep up with the crop year stops being used, and an exporter's website that says last year's harvest is worse than no website at all.
The dashboard
Every section above has a management screen, with an image gallery, role-based permissions, per-user overrides, a message inbox from the contact form and email notification through Nodemailer.
How it was built
- Framework
SvelteKit
Server load functions, form actions and endpoints; SSR by default.
Svelte 5
Runes for reactivity ($state, $derived, $effect).
- Language
TypeScript
Strict mode across app and server code.
- Data
MySQL
Primary datastore.
Drizzle Kit
Committed SQL migrations rather than push-to-prod diffing.
Drizzle ORM
Typed schema and queries, with migrations generated from the schema.
- Auth
Better Auth
Session-based auth with server-side verification.
- Forms
Superforms
Progressive-enhancement forms with server-side validation.
Zod
One schema validating both client and server.
- UI
TanStack Table
Sorting, filtering and pagination for admin tables.
Chart.js
Reporting charts.
Dark mode
System-aware theme switching.
Lucide
Icon set.
Bits UI
Headless primitives behind the component library.
Embla
Carousels.
Tailwind CSS
Utility-first styling with a project design token layer.
- Infrastructure
Client image compression
Uploads compressed in the browser before hitting the server.
Nodemailer
Transactional email over SMTP.
Inside the system