Skip to content

Commit a07dfeb

Browse files
committed
Add ObjectOS AI coding standards and update docs
Introduced the .cursorrules file with detailed AI coding standards and architecture rules for ObjectOS. Updated .github/copilot-instructions.md to align with ObjectOS conventions and expanded implementation patterns. Overhauled README.md to reflect ObjectOS branding, architecture, quick start, and package structure, replacing ObjectQL-specific content.
1 parent 2d8fc9f commit a07dfeb

3 files changed

Lines changed: 500 additions & 210 deletions

File tree

.cursorrules

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
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

Comments
 (0)