One config, nine views
Most of an MVP's screens are the same screen: rows of domain objects that users want to browse, filter, drag around, and edit. Writing that screen per domain is where projects burn their time — and where agent-driven projects burn their tokens. The records feature in geenius-mvp exists to make that cost approach zero.
One EntityConfig
The shell ships an entity-view kit: nine interchangeable views — table, list, grid, kanban board, gallery, timeline, calendar, stats, and a draggable canvas — plus a generated create-and-edit form. All of them are driven by a single config. This is the real one from the template's RecordsPage.tsx:
const CONFIG: EntityConfig = {
labels: ["Record", "Records"],
titleKey: "title",
statusKey: "status",
dateKey: "dueDate",
imageKey: "imageUrl",
positionKey: "position",
amountKey: "amount",
fields: [
{ key: "title", label: "Title", type: "text", required: true },
{ key: "status", label: "Status", type: "select", options: STATUS_META },
{ key: "priority", label: "Priority", type: "select", options: PRIORITY_META },
{ key: "tags", label: "Tags", type: "tags" },
{ key: "dueDate", label: "Due", type: "date" },
{ key: "amount", label: "Amount", type: "number" },
{ key: "notes", label: "Notes", type: "longtext" },
{ key: "imageUrl", label: "Image", type: "image" },
{ key: "position", label: "Position", type: "position" },
],
};
Each FieldDef is a key, a label, and a type drawn from text, longtext, number, boolean, select, tags, date, image, and position — selects carry options with tones. The page itself is about 90 lines: it wires this config and four backend endpoints into EntityViews, a ViewSwitcher, and an EntityDetail modal. The views handle sorting, kanban drag, canvas drag, month paging, and stat aggregates on their own.
Role keys hide views for free
The role keys are the clever part. titleKey is required; the rest are optional and each one unlocks views. statusKey enables the board and stats breakdowns, dateKey enables timeline and calendar, imageKey enables the gallery, positionKey enables the canvas, amountKey adds totals to stats. Omit a role key and availableViews(CONFIG) simply stops offering the views that need it. There is no view-visibility configuration to maintain — the data model is the configuration.
The token economics
This is why AGENTS.md marks cloning records as the preferred way to add any data point. The recipe is three small edits: copy the schema block and rename it; copy convex/records.ts plus recordsShared.ts and adjust the validators (on Supabase, RLS is the backend, so it is one shared-constants file); copy the feature folder and edit the one CONFIG. Then register the feature with one import and one line.
For a human that is a fast afternoon shortcut. For an agent it changes the cost structure of the whole build. Writing nine views from scratch means generating thousands of lines of UI code, each line a chance to introduce a bug the agent then spends more tokens fixing. Cloning the pattern means generating a schema, some validators, and one config object — output that is short, declarative, and hard to get wrong. The views are data-agnostic (rows are objects with a string id, callbacks are onOpen, onPatch, onDelete) and themed by the shell's CSS variables, so the result looks finished immediately.
Do not rewrite view code per domain — extend the kit in the shell if a new view type is genuinely needed.
That rule, straight from the playbook, is the whole philosophy: view code is infrastructure, and infrastructure belongs in the shell, written once.