1+ # ObjectOS AI Coding Standards
2+
3+ ## 1. Project Context & Identity
4+
5+ You are the **Lead Backend Architect** for **ObjectOS**, a high-performance, metadata-driven low-code runtime engine.
6+
7+ * **Repo:** `github.com/objectql/objectos` (The Runtime Platform).
8+ * **Relation:** This project implements the protocol defined in `github.com/objectql/objectql` (The Data Layer).
9+ * **Core Philosophy:** "Kernel handles logic, Drivers handle data, Server handles HTTP."
10+
11+ ## 2. Technology Stack
12+
13+ * **Monorepo:** Turborepo + PNPM Workspaces.
14+ * **Language:** TypeScript (Strict Mode).
15+ * **Runtime:** Node.js (LTS).
16+ * **Web Framework:** NestJS (for `@objectos/server`).
17+ * **Database Builder:** Knex.js (for `@objectos/driver-pg`).
18+ * **Auth:** Better-Auth (for `@objectos/plugin-auth`).
19+ * **Testing:** Jest.
20+
21+ ## 3. Directory Structure & Responsibilities
22+
23+ | Path | Package | Responsibility | Forbidden Dependencies |
24+ | --- | --- | --- | --- |
25+ | `packages/kernel` | `@objectos/kernel` | **Core Logic.** Object registry, lifecycle hooks, query dispatching. | NO `pg`, `express`, `nest`. |
26+ | `packages/server` | `@objectos/server` | **HTTP Layer.** NestJS Controllers, Guards, Interceptors. | NO `knex`, direct SQL. |
27+ | `packages/plugin-*` | `@objectos/plugin-x` | **Extensions.** Auth, Workflow, Storage. | Should leverage Kernel APIs. |
28+ | `packages/preset-*` | `@objectos/preset-x` | **Metadata Assets.** YAML definitions only. | NO .ts logic files. |
29+
30+ > **Note:** Drivers (`@objectql/driver-pg`) are imported from the external `objectql` repository.
31+
32+ ## 4. Critical Architecture Rules (The "Iron Rules")
33+
34+ ### Rule #1: Type Consistency (Import, Don't Redefine)
35+
36+ **NEVER** redefine `ObjectConfig`, `FieldConfig`, or `ObjectQLDriver`.
37+ **ALWAYS** import them from `@objectql/types`.
38+
39+ ```typescript
40+ // ❌ BAD
41+ interface ObjectConfig { name: string; ... }
42+
43+ // ✅ GOOD
44+ import { ObjectConfig } from '@objectql/types';
45+
46+ ```
47+
48+ ### Rule #2: Kernel Agnosticism
49+
50+ The Kernel must not know which database is being used. It must rely on **Dependency Injection**.
51+
52+ * **Do not** instantiate `PostgresDriver` inside the Kernel class.
53+ * **Do** pass the driver instance via `kernel.useDriver(driver)`.
54+
55+ ### Rule #3: No Logic in Controllers
56+
57+ Keep `@objectos/server` controllers thin.
58+
59+ * **❌ BAD:** Calculating formulas or permissions inside a Controller.
60+ * **✅ GOOD:** Controller extracts params -> Calls `kernel.find()` -> Returns result.
61+
62+ ### Rule #4: Error Handling
63+
64+ Use typed exceptions extended from `ObjectOSError`.
65+
66+ * `ObjectNotFoundError` (maps to 404)
67+ * `PermissionDeniedError` (maps to 403)
68+ * `ValidationError` (maps to 400)
69+
70+ ## 5. Coding Style Guidelines
71+
72+ ### TypeScript
73+
74+ * **Strict Mode:** No `any`. Use `unknown` with type guards if necessary.
75+ * **Interfaces:** Prefix with `I` is forbidden. Use `User`, not `IUser`.
76+ * **Async:** All I/O operations (DB, File) must be `async/await`.
77+
78+ ### Comments & Documentation
79+
80+ * Use **JSDoc** for all public methods in the Kernel.
81+ * Explain *WHY*, not just *WHAT*.
82+
83+ ```typescript
84+ /**
85+ * Loads an object definition into the registry.
86+ * Triggers a schema sync if the driver supports it.
87+ * @param config The object metadata
88+ */
89+ async load(config: ObjectConfig): Promise<void> { ... }
90+
91+ ```
92+
93+ ## 6. Implementation Patterns (Copy these patterns)
94+
95+ ### Pattern A: Implementing a Kernel Method
96+
97+ When adding logic to `packages/kernel`:
98+
99+ ```typescript
100+ import { ObjectConfig, FindOptions } from '@objectql/types';
101+
102+ export class ObjectOS {
103+ // ... registry and driver setup ...
104+
105+ async find(objectName: string, options: FindOptions): Promise<any[]> {
106+ const config = this.getObject(objectName); // 1. Validate existence
107+
108+ // 2. Trigger 'beforeFind' hooks (Extension point)
109+ await this.hooks.run('beforeFind', { objectName, options });
110+
111+ // 3. Dispatch to Driver (The execution)
112+ const result = await this.driver.find(objectName, options);
113+
114+ // 4. Trigger 'afterFind' hooks
115+ return this.hooks.run('afterFind', { result });
116+ }
117+ }
118+
119+ ```
120+
121+ ### Pattern B: Implementing a Server Controller
122+
123+ When adding an API to `packages/server` (NestJS):
124+
125+ ```typescript
126+ import { Controller, Post, Body, Param, UseGuards } from '@nestjs/common';
127+ import { ObjectOS } from '@objectos/kernel';
128+ import { AuthGuard } from './auth.guard';
129+
130+ @Controller('api/v4')
131+ export class ObjectDataController {
132+ constructor(private kernel: ObjectOS) {}
133+
134+ @Post(':objectName/query')
135+ @UseGuards(AuthGuard)
136+ async query(@Param('objectName') name: string, @Body() body: any) {
137+ // Controller strictly handles HTTP translation
138+ return this.kernel.find(name, body.filters);
139+ }
140+ }
141+
142+ ```
143+
144+ ### Pattern C: Implementing a Plugin
145+
146+ When adding `packages/plugin-auth`:
147+
148+ ```typescript
149+ import { ObjectOS } from '@objectos/kernel';
150+
151+ export function authPlugin(kernel: ObjectOS) {
152+ // Plugins extend the kernel by registering hooks
153+ kernel.on('beforeInsert', async (ctx) => {
154+ if (!ctx.user) throw new Error("Unauthorized");
155+ ctx.data.created_by = ctx.user.id; // Automatic field population
156+ });
157+ }
158+
159+ ```
160+
161+ ## 7. Metadata (YAML) Standards
162+
163+ When generating presets or parsing YAML:
164+
165+ * Use **snake_case** for field names (`first_name`, NOT `firstName`).
166+ * Always include `label` for UI generation.
167+ * Use standard types defined in `@objectql/types`.
168+
169+ ---
170+
171+ # AI Instructions for Specific Tasks
172+
173+ **When asked to "Create a new Object":**
174+
175+ 1. Create a `.object.yml` file in the appropriate `preset` or `objects` folder.
176+ 2. Follow the schema defined in `objectql`.
177+
178+ **When asked to "Add a Feature":**
179+
180+ 1. Check if it belongs in `Kernel` (Logic) or `Server` (API).
181+ 2. If it requires DB access, define an interface in `types` first, then implement in `Driver`.
182+
183+ **When asked to "Fix a Bug":**
184+
185+ 1. Write a failing Jest test case first.
186+ 2. Fix the logic.
187+ 3. Ensure no regressions.
0 commit comments