Skip to content

Commit cd2fac0

Browse files
committed
Add index and unique support to field and object configs
Introduces 'index' and 'unique' properties to FieldConfig and documents their usage. Adds IndexConfig and 'indexes' to ObjectConfig for composite and unique indexes. Updates documentation to clarify field-level and object-level index definitions and constraints.
1 parent b09cc53 commit cd2fac0

4 files changed

Lines changed: 53 additions & 8 deletions

File tree

.github/copilot-instructions.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ We use **Turborepo** + **PNPM Workspaces**.
1515
| Path | Package Name | Environment | Role | Description |
1616
| --- | --- | --- | --- | --- |
1717
| `packages/types` | `@objectql/types` | **Universal** | **The Contract** | Pure TS Interfaces, Enums, and Error Classes. **No deps.** |
18-
| `packages/parser` | `@objectql/parser` | **Universal** | **The Compiler** | YAML string -> JSON AST. Pure logic. |
1918
| `packages/core` | `@objectql/core` | **Universal** | **The Engine** | Main entry point (`ObjectQL` class). Connects Drivers & Registry. |
2019
| `packages/driver-pg` | `@objectql/driver-pg` | **Node.js** | **The Adapter** | Postgres implementation. Depends on `knex` or `pg`. |
2120
| `packages/driver-mongo` | `@objectql/driver-mongo` | **Node.js** | **The Adapter** | MongoDB implementation. |
@@ -60,12 +59,6 @@ You must strictly enforce the following dependency rules:
6059

6160
* **Role:** It orchestrates the flow. It validates the request using `SimpleRegistry` and delegates execution to the injected `driver`.
6261

63-
### 📦 `packages/parser`
64-
65-
* **Content:** `function parse(yaml: string): ObjectConfig`
66-
* **Role:** Pure transformation. Uses `js-yaml`. Validation via `zod` (optional).
67-
* **Output:** Must strictly match `ObjectConfig` from `types`.
68-
6962
### 📦 `packages/driver-*`
7063

7164
* **Content:** Implementation of `ObjectQLDriver`.

docs/spec/object.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ fields:
3232
| `type` | `string` | **Required.** Data type of the field. |
3333
| `label` | `string` | Display label for UI validation messages. |
3434
| `required` | `boolean` | If `true`, the field cannot be null/undefined. Default: `false`. |
35+
| `unique` | `boolean` | If `true`, enforces unique values in the database. Default: `false`. |
3536
| `defaultValue` | `any` | Default value if not provided during creation. |
36-
| `index` | `boolean` | Hint to create a database index. |
37+
| `index` | `boolean` | Creates a database index for this field. |
3738
| `searchable` | `boolean` | Hint to include this field in global search. |
3839
| `sortable` | `boolean` | Hint that this field can be used for sorting in UI. |
3940
| `description` | `string` | Help text or documentation for the field. |
@@ -102,3 +103,43 @@ status:
102103
- label: In Progress
103104
value: in_progress
104105
```
106+
107+
## 3. Indexes
108+
109+
Indexes can be defined at the field level (for single-field indexes) or at the object level (for composite indexes).
110+
111+
### 3.1 Field-Level Indexes
112+
113+
You can define simple indexes directly on the field:
114+
115+
```yaml
116+
fields:
117+
email:
118+
type: email
119+
index: true # Creates a standard index
120+
unique: true # Creates a unique index (constraint)
121+
```
122+
123+
### 3.2 Object-Level Indexes
124+
125+
For composite indexes (spanning multiple fields), define them under the `indexes` key at the root of the file.
126+
127+
```yaml
128+
indexes:
129+
# Index Name: Index Definition
130+
131+
# Composite Index
132+
project_status_idx:
133+
fields: [project_id, status]
134+
135+
# Unique Composite Index
136+
unique_task_name:
137+
fields: [project_id, name]
138+
unique: true
139+
```
140+
141+
| Property | Type | Description |
142+
| :--- | :--- | :--- |
143+
| `fields` | `string[]` | **Required.** List of field names to include in the index. |
144+
| `unique` | `boolean` | If `true`, requires values to be unique combination. Default: `false`. |
145+

packages/types/src/field.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ export interface FieldConfig {
6969
/** Whether the field is unique in the table. */
7070
unique?: boolean;
7171

72+
/** Whether to create a database index for this field. */
73+
index?: boolean;
74+
7275
/** Whether the field is read-only in UI. */
7376
readonly?: boolean;
7477

packages/types/src/object.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { FieldConfig } from './field';
22
import { ActionConfig } from './action';
33

4+
export interface IndexConfig {
5+
/** List of fields involved in the index */
6+
fields: string[];
7+
/** Whether the index enforces uniqueness */
8+
unique?: boolean;
9+
}
10+
411
export interface ObjectConfig {
512
name: string;
613
datasource?: string; // The name of the datasource to use
@@ -9,5 +16,6 @@ export interface ObjectConfig {
916
description?: string;
1017

1118
fields: Record<string, FieldConfig>;
19+
indexes?: Record<string, IndexConfig>;
1220
actions?: Record<string, ActionConfig>;
1321
}

0 commit comments

Comments
 (0)