|
| 1 | +--- |
| 2 | +title: Core Concepts |
| 3 | +description: The foundational ideas behind ObjectStack — metadata-driven development, protocol-first design, and the principles that shape every decision |
| 4 | +--- |
| 5 | + |
| 6 | +import { Scale, Code2, Database, ScrollText, Laptop } from 'lucide-react'; |
| 7 | + |
| 8 | +# Core Concepts |
| 9 | + |
| 10 | +Before diving into code, understanding these foundational ideas will make everything else click. |
| 11 | + |
| 12 | +## Metadata-Driven Development |
| 13 | + |
| 14 | +Metadata-driven development is a paradigm shift where **application logic is defined by declarative data (metadata), not imperative code.** |
| 15 | + |
| 16 | +### The Problem with Code-First |
| 17 | + |
| 18 | +In traditional development, the "Intent" (e.g., *"This field is a required email address"*) is scattered across multiple layers: |
| 19 | + |
| 20 | +1. **Database:** SQL constraints (`NOT NULL`, `CHECK`) |
| 21 | +2. **Backend:** ORM validation (TypeORM decorators, Prisma schemas) |
| 22 | +3. **Frontend:** UI validation (React Hook Form + Zod) |
| 23 | +4. **Documentation:** API specs (OpenAPI/Swagger) |
| 24 | + |
| 25 | +When a business requirement changes, you must update code in **three or four places**. This is **Implementation Coupling**. |
| 26 | + |
| 27 | +### The ObjectStack Way |
| 28 | + |
| 29 | +ObjectStack centralizes the "Intent" into a **single Protocol Definition**: |
| 30 | + |
| 31 | +```typescript |
| 32 | +// ONE definition — everything else derives from it |
| 33 | +import { defineStack } from '@objectstack/spec'; |
| 34 | + |
| 35 | +export default defineStack({ |
| 36 | + objects: [{ |
| 37 | + name: 'user', |
| 38 | + label: 'User', |
| 39 | + fields: [ |
| 40 | + { name: 'phone', label: 'Phone Number', type: 'phone', required: true }, |
| 41 | + ], |
| 42 | + }], |
| 43 | +}); |
| 44 | +``` |
| 45 | + |
| 46 | +From this single definition, ObjectStack automatically: |
| 47 | + |
| 48 | +✅ Generates database schema |
| 49 | +✅ Creates validation rules |
| 50 | +✅ Builds CRUD APIs |
| 51 | +✅ Renders form fields |
| 52 | +✅ Produces API documentation |
| 53 | + |
| 54 | +### The Three Truths |
| 55 | + |
| 56 | +1. **The UI is a Projection** — The form is generated from the schema, not hand-coded |
| 57 | +2. **The API is a Consequence** — REST/GraphQL endpoints appear automatically from object definitions |
| 58 | +3. **The Schema is the Application** — Your entire business logic lives in metadata files |
| 59 | + |
| 60 | +### When to Use Metadata-Driven |
| 61 | + |
| 62 | +✅ **Great for:** CRUD apps, SaaS platforms, admin panels, rapid prototyping, multi-tenant systems |
| 63 | + |
| 64 | +❌ **Not ideal for:** Pixel-perfect custom UIs, real-time 3D/games, highly unique domains |
| 65 | + |
| 66 | +--- |
| 67 | + |
| 68 | +## Design Principles |
| 69 | + |
| 70 | +ObjectStack is governed by four unshakable principles: |
| 71 | + |
| 72 | +<Cards> |
| 73 | + <Card |
| 74 | + icon={<Scale />} |
| 75 | + title="I. Protocol Neutrality" |
| 76 | + description="The Protocol is law. The Implementation is merely an opinion." |
| 77 | + /> |
| 78 | + <Card |
| 79 | + icon={<Code2 />} |
| 80 | + title="II. Mechanism over Policy" |
| 81 | + description="Provide the tools to build rules, do not hardcode the rules themselves." |
| 82 | + /> |
| 83 | + <Card |
| 84 | + icon={<Database />} |
| 85 | + title="III. Single Source of Truth" |
| 86 | + description="There is no 'Code'. There is only Schema." |
| 87 | + /> |
| 88 | + <Card |
| 89 | + icon={<ScrollText />} |
| 90 | + title="IV. Local-First by Default" |
| 91 | + description="The Cloud is a sync peer, not a master." |
| 92 | + /> |
| 93 | +</Cards> |
| 94 | + |
| 95 | +### Protocol Neutrality |
| 96 | + |
| 97 | +**"The Protocol is neutral. The Engine is replaceable."** |
| 98 | + |
| 99 | +- **Spec before Engine:** Features must be defined in the Specification layer before any engine code is written |
| 100 | +- **Zero Leakage:** Implementation details (React, SQL, etc.) never leak into Protocol definitions |
| 101 | + |
| 102 | +This ensures ObjectStack apps can run on Node.js + PostgreSQL today, Python + SQLite tomorrow, or Rust WASM in the browser. |
| 103 | + |
| 104 | +### Mechanism over Policy |
| 105 | + |
| 106 | +**"Give them the physics, not the simulation."** |
| 107 | + |
| 108 | +| Layer | Responsibility | Example | |
| 109 | +| :--- | :--- | :--- | |
| 110 | +| **Protocol** | Defines capabilities | `allowRead: string` (a slot for a formula) | |
| 111 | +| **App** | Defines business logic | `allowRead: "$user.role == 'admin'"` | |
| 112 | +| **Engine** | Enforces the logic | Compiles formula to SQL `WHERE` clause | |
| 113 | + |
| 114 | +### Single Source of Truth |
| 115 | + |
| 116 | +In ObjectStack, **the Object Protocol is the only truth:** |
| 117 | + |
| 118 | +- The Database is a *derivative* of the Protocol |
| 119 | +- The UI is a *projection* of the Protocol |
| 120 | +- The API is a *consequence* of the Protocol |
| 121 | + |
| 122 | +Change the Protocol → the entire system adapts automatically. |
| 123 | + |
| 124 | +### Local-First by Default |
| 125 | + |
| 126 | +All interactions should be instant (0ms latency). The user's data lives on their device; the server is a sync hub. |
| 127 | + |
| 128 | +``` |
| 129 | +Traditional: Click → Wi-Fi → ISP → Cloud → DB → Response |
| 130 | +Local-First: Click → Local DB → UI Update (0ms) |
| 131 | +``` |
| 132 | + |
| 133 | +--- |
| 134 | + |
| 135 | +## Naming Conventions |
| 136 | + |
| 137 | +ObjectStack enforces strict naming rules for consistency: |
| 138 | + |
| 139 | +| Element | Convention | Examples | |
| 140 | +|---------|-----------|----------| |
| 141 | +| **Object names** (machine) | `snake_case` | `todo_task`, `user_profile` | |
| 142 | +| **Field names** (machine) | `snake_case` | `first_name`, `is_active` | |
| 143 | +| **Export names** (constants) | `PascalCase` | `TodoTask`, `UserProfile` | |
| 144 | +| **Config keys** (properties) | `camelCase` | `maxLength`, `defaultValue` | |
| 145 | + |
| 146 | +## Summary |
| 147 | + |
| 148 | +| Aspect | Traditional | Metadata-Driven | |
| 149 | +| :--- | :--- | :--- | |
| 150 | +| **Definition** | Code in multiple files | Single metadata definition | |
| 151 | +| **Changes** | Update 3-4 places | Update once | |
| 152 | +| **Type Safety** | Manual synchronization | Automatic from Zod | |
| 153 | +| **Flexibility** | Locked to tech stack | Technology agnostic | |
| 154 | +| **Boilerplate** | High (300+ lines) | Low (30 lines) | |
| 155 | + |
| 156 | +## Next Steps |
| 157 | + |
| 158 | +- [Architecture](/docs/getting-started/architecture) — How the protocol layers work together |
| 159 | +- [Quick Start](/docs/getting-started/quick-start) — Build your first app in 5 minutes |
| 160 | +- [Glossary](/docs/getting-started/glossary) — Key terminology |
0 commit comments