Features:
- Create notes with Farcaster profile (fid, username, displayName, pfp) via MiniKit.
- Author is stored as JSON field
authorin each post. - Feed: avatar on the left, name above the card, content inside; clicking avatar -> profile.
- Profile page
/profile/[id]whereidisusernameorfid.
Architecture and routes:
- Storage:
data/posts.json(with migration fromnotes.json). - API:
GET/POST /api/postsPOSTaccepts{ text, cid, author? }, whereauthor = { fid, username?, displayName?, pfp? }.GET ?author={username|fid}— posts by author;?cid=...addsuserVoteandcanEdit.
PUT/DELETE /api/posts/[id]— edit/delete only by owner (ownerCid).POST /api/posts/vote— like/dislike, tracked bycid.GET /api/author/last?cid=...— last non-empty author byownerCid(server-side cache).
- UI:
components/CreateNote.jsx— input, profile request (MiniKit), POST.components/NotesList.jsx— feed, optimistic insert.components/NoteItem.jsx— card, avatar link, name, content, owner edit/delete, voting.app/profile/[id]/page.jsx— profile, avatar+name+counter+feed.
MiniKit (important):
sdk.actions.requestUser()is called only when creating a post and only in the Mini App context.- MiniKit does NOT work on localhost/regular browser — test via Vercel (Base App Preview/Prod).
- In the Farcaster mini app the SDK returns real
pfp/username/displayName/fid.
Local development:
- Node LTS, npm.
- Install:
npm install - Run:
npm run dev(http://localhost:3000) - On localhost MiniKit profile won’t be fetched — that’s expected. Author fields may be empty.
Public assets:
- Fallback avatar:
/public/images/default-avatar.png - Font:
/public/fonts/DigitalPixelV124-Regular.woff2 - Paths in code start with
/images/...,/fonts/...— correct for Next.jspublic/.
Project configuration:
- Scripts
package.json:dev,build,start— suitable for Vercel. - Next.js config
next.config.mjs:reactStrictModeandexperimental.appDirenabled. - Vercel config
vercel.json:"buildCommand": "npm run build","outputDirectory": ".next".
Deploy to Vercel — via GitHub:
- Initialize repo:
git initgit add -Agit commit -m "init"- Create an empty GitHub repo and connect:
git branch -M maingit remote add origin https://github.com/<user>/<repo>.gitgit push -u origin main
- Vercel:
- https://vercel.com → New Project → Import Git Repository → select your repo.
- Framework: Next.js (Auto)
- Root Directory:
/ - Build Command:
npm run build - Output Directory:
.next - Env (optional):
NEXT_PUBLIC_BASE_URL=https://<project>.vercel.app(if not set, the frontend uses relative paths — also fine)
- Deploy.
Deploy to Vercel — via CLI:
- Install CLI:
npm i -g vercel - Login:
vercel login - First deploy (project linking):
vercel - Production deploy:
vercel --prod - Explicitly set commands (if needed):
vercel --build-command "npm run build" --output .next
Post-deploy checklist:
npm run buildpasses without errors (see Vercel logs).- In the Farcaster mini app
sdk.actions.requestUser()fetches real profiles. - Avatars/names/cards are rendered correctly on the home page.
- Clicking avatar navigates to
/profile/{username|fid}. - Profile page shows avatar, name, posts counter, and the feed.
- Fallback avatar works (when
pfpis absent).
Data persistence on Vercel (important):
- Storage adapter in lib/storage.js выбирает бэкенд автоматически:
- Vercel + KV_REST_API_URL и KV_REST_API_TOKEN заданы → используется Vercel KV по REST (персистентно между деплоями).
- Vercel без KV-переменных → in-memory (globalThis.MEM_POSTS), данные эфемерные, но ошибок EROFS не будет (на файловую систему ничего не пишется).
- Локально → файл data/posts.json (автоматическое создание папки/файла, миграция из notes.json при наличии).
- API-роуты и UI не меняются при смене бэкенда, всё инкапсулировано в адаптере lib/storage.js.
How to enable persistent storage on Vercel (KV):
- В проекте Vercel открой Storage → подключи “KV” (или Upstash Redis) к проекту (Project → Storage → Add → KV).
- Убедись, что в Settings → Environment Variables автоматически появились переменные:
- KV_REST_API_URL
- KV_REST_API_TOKEN Если не появились — добавь вручную значениями из панели Vercel KV.
- Redeploy (или “Deploy” в панели Vercel). Ничего ставить через npm не нужно: используется REST-клиент (fetch), зависимость @vercel/kv не требуется.
Troubleshooting (Vercel):
- 500 EROFS при POST/GET /api/posts или /api/author/last означает, что адаптер пытался писать в FS. Это происходит только если нет KV-переменных и нет перехода в in-memory режим. Проверь, что деплой обновлён, а переменные KV_REST_API_URL/KV_REST_API_TOKEN заданы; либо временно работай в эфемерной памяти.
- Пустые имя/аватар локально — ожидаемо: MiniKit не работает на localhost. Автор может быть пустым. В коде есть серверный хелпер app/api/author/last/route.js, который подтягивает последнего автора по
ownerCid(см. клиент components/CreateNote.jsx).
MiniKit:
- Вызов профиля выполняется только при создании поста в components/CreateNote.jsx через sdk.actions.requestUser.
- В проде (через Base App/Mini App) MiniKit вернёт реальные fid/username/displayName/pfp. На localhost MiniKit не сработает — это норма. Structure (main):
- App:
app/page.jsx, layout:app/layout.jsx - API:
app/api/posts/route.js,app/api/posts/[id]/route.js,app/api/posts/vote/route.js,app/api/author/last/route.js - Components:
components/CreateNote.jsx,components/NotesList.jsx,components/NoteItem.jsx,components/NoteVotes.jsx - Profile:
app/profile/[id]/page.jsx - Styles:
styles/globals.css - Public assets:
public/images/default-avatar.png,public/fonts/DigitalPixelV124-Regular.woff2
Ignore files (recommended):
.gitignore:node_modules/ .next/ .vercel/ .env* npm-debug.log* yarn-error.log*.vercelignore(optional, so you don’t ship legacy assets into the build):Minimal-Notes/ minimal_notes_server.py DigitalPixelV124-Regular.woff2.otf notes.json
MiniKit integration notes:
- MiniKit requestUser вызывается только при создании поста (в компоненте CreateNote, см. import sdk и sdk.actions.requestUser).
- MiniKit НЕ работает на localhost — тестировать Mini App надо через Vercel/Prod окружение.
- В деве сохранение постов локально работает, автор подтягивается повторно по последнему посту этого клиента (/api/author/last).
- Base App автоматически отдаёт реальные pfp/username/displayName в мини-приложении (после деплоя).
Deployment:
- Локально: npm run dev (requestUser не сработает — это ожидаемо).
- Прод: Vercel. После деплоя MiniKit покажет natively pfp/username и вернёт fid/username/displayName/pfp.
Data model:
- posts.author хранится как JSON: { fid: number, username?: string, displayName?: string, pfp?: string }.
- Fallback-аватар: /public/images/default-avatar.png.