i want to build an online blog that can transform agriculture, food and agribusiness in Tanzania and Africa. I own Winland Farms Limited, look it on Google. I want the blog to have influence in Africa and globally. The blog should be more useful and professional and bigger than techcabal and agriNaigeria combined.
# HarvestWire — CMS & API Backend
Strapi v4 (Node.js) on PostgreSQL, exposing both REST and GraphQL, built for a global agribusiness/food-tech publication.
## Stack
- **Strapi v4** — admin panel, content modeling, RBAC, media library
- **PostgreSQL** — primary datastore, plus native full-text search via `tsvector`
- **GraphQL** (`@strapi/plugin-graphql`) — optimized query layer for the Next.js frontend
- **Cloudinary** (`@strapi/provider-upload-cloudinary`) — automatic image compression/format optimization on upload
## Getting started
```bash
cp .env.example .env # fill in real secrets — see "Generating secrets" below
npm install
npm run develop # starts Strapi with admin panel + auto-reload
```
First run opens `
localhost` to create your Super Admin account.
### Generating secrets
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
```
Run this four times for `APP_KEYS` (comma-separated) and once each for `API_TOKEN_SALT`, `ADMIN_JWT_SECRET`, `TRANSFER_TOKEN_SALT`, `JWT_SECRET`. Never commit `.env`.
## Content model
| Content type | Purpose | Key fields |
|---|---|---|
| `Article` | A story | `title`, `slug` (auto), `content` (richtext), `excerpt`, `featuredImage`, `author`, `category`, `tags`, `reviewStatus` (draft/in_review/published), `publishedAt` (Strapi's native draft/publish toggle) |
| `Author` | Byline | `name`, `bio`, `avatar`, `role`, `socialLinks` (repeatable component), optional link to a `users-permissions` user account |
| `Category` | Sector/sub-sector | `name`, `slug`, `description`, `parent` (self-relation — e.g. AgTech → Drones) |
| `Tag` | Cross-cutting label | `name`, `slug` |
| `MarketData` | Commodity ticker feed | `commodityName`, `symbol`, `price`, `changePercent`, `region`, `date` |
**Two different "status" concepts, on purpose:** `reviewStatus` tracks where a piece sits in the newsroom workflow (draft → in review → published editorially), while `publishedAt` (Stra …