- TypeScript 69.2%
- CSS 25.9%
- JavaScript 4.9%
Public idea submission + upvotes + a status board (Under Review → Planned → In Progress → Done), built on kapable-board (ideas as stories, columns as custom no-specialist lanes) + kapable-data (vote counts in feedback_votes). All platform IO server-side via the org key; the board status-board pattern uses setLanes + updateStory(status), not the Routa /transition path. |
||
|---|---|---|
| app | ||
| public | ||
| .gitignore | ||
| .npmrc | ||
| bun.lock | ||
| env.d.ts | ||
| package.json | ||
| react-router.config.ts | ||
| README.md | ||
| seed.ts | ||
| tsconfig.json | ||
| vite.config.ts | ||
Feedback / Feature-Request Board
A public idea board for the Kapable v2 platform: anyone can submit a feature request, upvote the ones they care about, and follow each idea through a status pipeline — Under Review → Planned → In Progress → Done.
Live: https://feedback.kapable-starters.kapable.run/
What it demonstrates
This is a kapable-board showcase (the status board) integrated with kapable-data (vote counts):
| Concern | Service | How |
|---|---|---|
| Ideas + columns | kapable-board |
One board Story per idea; a Product with four custom lanes. |
| Vote counts | kapable-data |
Table feedback_votes (story_id, votes), keyed by story id. |
Board pattern (important)
The board's /transition endpoint is the Routa agentic-coordination path —
it enforces lane adjacency and dispatches a specialist (which needs a codebase
ref). A plain status board must not use it. Instead this app:
- Creates a product, then sets columns with
setLanes()(no specialist). - Moves a card with
updateStory({ status })— a plain PATCH that bypasses the lane graph and dispatch.
Architecture
- React Router 7 SSR. All platform IO is server-side (
app/lib/*.server.ts); the org key never reaches the browser. app/lib/feedback.ts— client-safe constants/types (columns, theIdeaDTO).app/lib/feedback.server.ts— the data layer (board + data via@kapable/sdk).app/routes/home.tsx— the board UI: submit form, vote buttons, status columns, empty state. One route, intent-dispatched action (submit|upvote|move).
Credential
The app authenticates to the platform with a single long-lived org API key,
provided as the server-only deploy secret KAPABLE_ORG_KEY (an sk_live_
key scoped {read, write}). It is never committed and never in the client bundle.
Develop
bun install
KAPABLE_ORG_KEY=sk_live_... bun run dev
Build
bun run build && bun run start # serves on :3000