Skip to content

CreatorTrack App Model , Collections + Custom View-Blocks

URL: https://mkdocs.justinsforge.com/memory/plans/creatortrack-app-model-collections-and-view-blocks-2026-06-19/

The architecture decision that resolves the recurring "is it a custom app or a database?" tension. Parent: [[creator-suite-vision-strategy-2026-06-17]], [[creatortrack-roadmap-2026-06-18]]. Settled with Justin 2026-06-19.

The principle (one line)

Every app is a database + a view. Precisely: every app decomposes into Data + View + (optional) Feed + (optional) Compute. CreatorTrack provides one primitive for each, so a new app is a configuration of those primitives, not new plumbing.

Primitive What it is In CreatorTrack
Data the rows: a collection of typed properties + relations the collection engine (app.nodes + app.collection_props/_values/_views/_relations), already built
View how a human sees the rows collection_views + custom view-blocks (the new primitive)
Feed where data comes from (integration/sync) Forge pipelines (SimpleFIN for finance; same pattern for stocks/social)
Compute what gets derived (rollups, categorization, ranking, ML) rollups in-engine; custom React modules + AI for the hard parts

Worked examples

  • TickTick = tasks collection + list/board/calendar view. ~pure Data+View.
  • RocketMoney = transactions+accounts collections + a Feed (bank sync) + Compute (categorization, recurring detection, alerts) + custom view.
  • Stocks = holdings collection + a real-time market-data Feed + Compute (gains) + chart view.
  • Instagram = posts/users/follows collections, but the product is Feed (uploads) + Compute (ranking algorithm) + media CDN. Data model is a DB; product is not "just a DB".
  • Games = NOT a database+view (real-time simulation/render loop). The model's boundary.

"Just a database" is true of the data layer of nearly every tracking/business/creator app; it is false of the product when the value is mostly Feed (stocks) or Compute (IG ranking, games, video render). Those are the custom-module cases.

THE KEY DECISION: collections + custom view-blocks, NOT dedicated-table apps

Notion's power is one substrate: everything is a row in the same model, so relations/rollups/AI work across everything for free. Its limit is only ~6 built-in view renderers and you can't write a 7th.

CreatorTrack's edge = the same one-substrate data model + an open renderer set. - A habit is a row in a Habits collection (props: icon, goal, cadence), NOT a row in a separate app.habits table. So it can relate to a Project, be referenced in a doc, roll up into a dashboard, and the AI reads it with the same query path as everything else. - The polished UI (streaks, icons, animations) is a custom view-block: a bespoke React renderer registered as a new collection_views.type beyond the 6 built-ins, bound to the collection, embeddable as a block on any page. "Habits as a custom block" = a habit-tracker view of the Habits collection. - You don't choose between "database" and "custom app." A custom block IS a view of the database. Full interconnection underneath, unlimited custom UI on top.

Consequence for existing schema

  • The dedicated-table apps from the Flask prototype , app.habits/app.habit_logs (0009), app.time_entries (0010), app.meal_entries (0011) , are the WRONG fork: they bypass the collection model and become islands (no relations, AI must special-case each). Do NOT port them into CreatorTrack (React). Rebuild habits/food/time as collections + custom view-blocks. (Clean-slate rule: [[feedback_suite_clean_slate_rebuild]].)
  • Dedicated tables survive ONLY for genuine scale/special data: clips (video bytes on NVMe + pgvector embeddings) and finance (thousands of transactions). Even those expose a collection-style read contract so AI + relations stay uniform.

The new primitive to build (the "middle piece")

A custom view-block registry. Today collection_views.type is CHECK-constrained to table/board/calendar/gallery/list/timeline. The registry lets a node render a collection through an arbitrary registered React renderer (e.g. streak, habit-tracker, chart), selectable as a view and droppable as a block. This is the reusable foundation every future app (and eventually third-party apps , the app SDK) builds on. Building habits this way is the first proof of the registry.

Build implication

First proof = Habits as a collection + a streak custom view-block (scope via /feature-plan). Food, fitness, time-tracking then follow the same recipe. The Telegram capture/read cutover ([[reference_forge_data_lifeos_spine]]) rides the same collection contract so the bot, the UI, and AI all read one model.

[Claude Code]