@abeedoo/radish-schemas 1.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +317 -0
- package/index.js +38 -0
- package/package.json +51 -0
- package/prompts/index.js +118 -0
- package/prompts/radish-app-generation.md +259 -0
- package/prompts/radish-components-generation.md +138 -0
- package/prompts/radish-roles-generation.md +133 -0
- package/prompts/radish-schema-generation.md +267 -0
- package/prompts/radish-theme-generation.md +138 -0
- package/prompts/radish-types-generation.md +294 -0
- package/prompts/radish-ui-generation.md +227 -0
- package/schemas/app.schema.json +289 -0
- package/schemas/components.schema.json +199 -0
- package/schemas/index.js +49 -0
- package/schemas/roles.schema.json +64 -0
- package/schemas/theme.schema.json +196 -0
- package/schemas/types.schema.json +761 -0
- package/schemas/ui.schema.json +346 -0
- package/validators/index.js +175 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# AI UI Blueprint Generation Prompt
|
|
2
|
+
|
|
3
|
+
You are an expert UI architect. Generate a JSON UI blueprint that defines routes, pages, layouts, and content blocks for a web application.
|
|
4
|
+
|
|
5
|
+
**Generate ONLY the UI blueprint. Do NOT include types, roles, or app metadata.**
|
|
6
|
+
|
|
7
|
+
The UI blueprint references entities defined in the types blueprint. Content blocks are entity-driven — the generator reads entity metadata (fields, types, relationships) to auto-generate tables, forms, and detail views.
|
|
8
|
+
|
|
9
|
+
## Blueprint Structure
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"version": 1,
|
|
14
|
+
"app": {
|
|
15
|
+
"name": "AppName",
|
|
16
|
+
"description": "Short description for display"
|
|
17
|
+
},
|
|
18
|
+
"routes": [
|
|
19
|
+
{
|
|
20
|
+
"path": "/",
|
|
21
|
+
"page": "home",
|
|
22
|
+
"title": "Home",
|
|
23
|
+
"access": "public"
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"pages": {
|
|
27
|
+
"home": {
|
|
28
|
+
"layout": {
|
|
29
|
+
"header": true,
|
|
30
|
+
"navigation": true,
|
|
31
|
+
"footer": true
|
|
32
|
+
},
|
|
33
|
+
"content": [
|
|
34
|
+
{ "type": "hero", "title": "Welcome to {app.name}", "subtitle": "{app.description}" }
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Routes
|
|
42
|
+
|
|
43
|
+
Each route maps a URL path to a page definition.
|
|
44
|
+
|
|
45
|
+
**Properties:**
|
|
46
|
+
- `path` (required): URL pattern. Use `[param]` for dynamic segments
|
|
47
|
+
- `page` (required): Page identifier (lowercase-hyphenated, must match a key in `pages`)
|
|
48
|
+
- `title` (optional): Page title for navigation and breadcrumbs
|
|
49
|
+
- `access` (required): One of:
|
|
50
|
+
- `"public"` — anyone can access
|
|
51
|
+
- `"authenticated"` — logged-in users only
|
|
52
|
+
- `{ "roles": ["ADMIN"], "permissions": ["entity:action"] }` — role/permission-based
|
|
53
|
+
|
|
54
|
+
**Route path patterns:**
|
|
55
|
+
```json
|
|
56
|
+
{ "path": "/", "page": "home", "access": "public" }
|
|
57
|
+
{ "path": "/courses", "page": "courses-list", "access": "authenticated" }
|
|
58
|
+
{ "path": "/courses/[id]", "page": "course-detail", "access": "authenticated" }
|
|
59
|
+
{ "path": "/courses/create", "page": "course-create", "access": { "roles": ["ADMIN", "INSTRUCTOR"] } }
|
|
60
|
+
{ "path": "/courses/[courseId]/modules", "page": "modules-list", "access": "authenticated" }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Pages
|
|
64
|
+
|
|
65
|
+
Each page has an optional layout and an array of content blocks.
|
|
66
|
+
|
|
67
|
+
**Layout properties (all boolean, all optional):**
|
|
68
|
+
- `header` — show application header
|
|
69
|
+
- `navigation` — show main navigation
|
|
70
|
+
- `sidebar` — show sidebar
|
|
71
|
+
- `footer` — show application footer
|
|
72
|
+
|
|
73
|
+
## Content Block Types
|
|
74
|
+
|
|
75
|
+
### 1. `hero`
|
|
76
|
+
Landing section with title and subtitle.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"type": "hero",
|
|
81
|
+
"title": "Welcome to {app.name}",
|
|
82
|
+
"subtitle": "{app.description}"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Supports interpolation: `{app.name}`, `{app.description}`
|
|
87
|
+
|
|
88
|
+
### 2. `entity-list`
|
|
89
|
+
Display a list/table/grid of entities. Fields auto-detected from entity metadata if not specified.
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"type": "entity-list",
|
|
94
|
+
"entity": "Course",
|
|
95
|
+
"display": "table",
|
|
96
|
+
"title": "All Courses",
|
|
97
|
+
"limit": 20,
|
|
98
|
+
"fields": ["title", "status", "createdAt"],
|
|
99
|
+
"filter": {
|
|
100
|
+
"field": "instructorId",
|
|
101
|
+
"value": "{user.id}"
|
|
102
|
+
},
|
|
103
|
+
"sort": {
|
|
104
|
+
"field": "createdAt",
|
|
105
|
+
"direction": "desc"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- `entity` (required): PascalCase entity name from types blueprint
|
|
111
|
+
- `display`: `"table"`, `"grid"`, or `"list"` (default: `"table"`)
|
|
112
|
+
- `title`: Section heading
|
|
113
|
+
- `limit`: Max items to display
|
|
114
|
+
- `fields`: Array of field names to show (omit to auto-detect from entity)
|
|
115
|
+
- `filter`: Filter by field/value with interpolation support
|
|
116
|
+
- `sort`: Default sort field and direction (`"asc"` or `"desc"`)
|
|
117
|
+
|
|
118
|
+
### 3. `entity-detail`
|
|
119
|
+
Display a single entity with its fields.
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"type": "entity-detail",
|
|
124
|
+
"entity": "Course",
|
|
125
|
+
"title": "Course Details",
|
|
126
|
+
"fields": ["title", "description", "price", "status"],
|
|
127
|
+
"actions": ["edit", "delete"]
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- `entity` (required): PascalCase entity name
|
|
132
|
+
- `title`: Section heading
|
|
133
|
+
- `fields`: Array of field names to show (omit to auto-detect)
|
|
134
|
+
- `actions`: Action buttons — `"edit"` and/or `"delete"`
|
|
135
|
+
|
|
136
|
+
### 4. `entity-form`
|
|
137
|
+
Create or edit form for an entity. Fields and validation auto-detected from entity metadata.
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"type": "entity-form",
|
|
142
|
+
"entity": "Course",
|
|
143
|
+
"action": "create",
|
|
144
|
+
"title": "Create Course",
|
|
145
|
+
"fields": ["title", "description", "price", "category"]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `entity` (required): PascalCase entity name
|
|
150
|
+
- `action`: `"create"` or `"edit"` (default: `"create"`)
|
|
151
|
+
- `title`: Form heading
|
|
152
|
+
- `fields`: Array of field names to include (omit to auto-detect)
|
|
153
|
+
|
|
154
|
+
## Interpolation
|
|
155
|
+
|
|
156
|
+
Content blocks support interpolation for dynamic values:
|
|
157
|
+
|
|
158
|
+
- `{app.name}` — Application name
|
|
159
|
+
- `{app.description}` — Application description
|
|
160
|
+
- `{entity.id}` — Current entity ID from route param (e.g., `{course.id}`)
|
|
161
|
+
- `{paramName}` — Route parameter (e.g., `{courseId}` from `/courses/[courseId]/modules`)
|
|
162
|
+
- `{user.id}` — Current logged-in user ID
|
|
163
|
+
|
|
164
|
+
## Design Guidelines
|
|
165
|
+
|
|
166
|
+
### Route Design
|
|
167
|
+
- Start with `/` as the landing page (usually `"public"`)
|
|
168
|
+
- Use CRUD patterns: `/entities` (list), `/entities/[id]` (detail), `/entities/create` (form)
|
|
169
|
+
- Nest related entities: `/courses/[courseId]/modules`
|
|
170
|
+
- Put admin routes behind role-based access
|
|
171
|
+
- Every route must have a matching page key
|
|
172
|
+
|
|
173
|
+
### Page Design
|
|
174
|
+
- Most pages should have `header: true`, `navigation: true`, `footer: true`
|
|
175
|
+
- Home page should have a hero block + featured entity list
|
|
176
|
+
- List pages: one `entity-list` block, typically `"table"` display
|
|
177
|
+
- Detail pages: one `entity-detail` block, optionally followed by related `entity-list` blocks
|
|
178
|
+
- Create/edit pages: one `entity-form` block
|
|
179
|
+
- Keep pages focused — one primary purpose per page
|
|
180
|
+
|
|
181
|
+
### Content Block Design
|
|
182
|
+
- Use `fields` arrays to control what's shown (otherwise all fields display)
|
|
183
|
+
- Use `filter` to show related entities (e.g., modules for a course)
|
|
184
|
+
- Use `limit` on home page previews (e.g., 5-6 featured items)
|
|
185
|
+
- Use `"grid"` display for visual content, `"table"` for data-heavy lists
|
|
186
|
+
- Add `actions: ["edit", "delete"]` on detail pages for authorized users
|
|
187
|
+
|
|
188
|
+
## What NOT to Include
|
|
189
|
+
- Individual field definitions (those come from types blueprint)
|
|
190
|
+
- Form validation rules (those come from entity metadata)
|
|
191
|
+
- Component implementations (the generator creates those)
|
|
192
|
+
- CSS/styling details (the generator applies the theme)
|
|
193
|
+
- API endpoints (the generator creates data loading)
|
|
194
|
+
|
|
195
|
+
## Built-in Entities Available for Reference
|
|
196
|
+
These can be used in content blocks without defining them in types:
|
|
197
|
+
- **User** — user profile pages, auth-related views
|
|
198
|
+
- **Profile** — user profile display/edit
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
**User Description**: {{USER_DESCRIPTION}}
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Response Format
|
|
207
|
+
|
|
208
|
+
You MUST respond with ONLY a valid JSON object starting with `{ "version": 1, "routes": [...], "pages": { ... } }`.
|
|
209
|
+
|
|
210
|
+
**CRITICAL REQUIREMENTS**:
|
|
211
|
+
1. Return ONLY the JSON object — no markdown code blocks, no explanations, no preamble
|
|
212
|
+
2. Must include `"version": 1`
|
|
213
|
+
3. Must include `"routes"` array with at least one route
|
|
214
|
+
4. Must include `"pages"` object with a key for every page referenced in routes
|
|
215
|
+
5. Every route `page` value must have a matching key in `pages`
|
|
216
|
+
6. Entity names must be PascalCase (e.g., `"Course"`, not `"course"`)
|
|
217
|
+
7. Page keys must be lowercase-hyphenated (e.g., `"course-detail"`, not `"courseDetail"`)
|
|
218
|
+
8. Do NOT include types, roles, or app blueprint content — UI only
|
|
219
|
+
|
|
220
|
+
**Common Mistakes to AVOID**:
|
|
221
|
+
- Wrapping response in markdown ```json...``` blocks
|
|
222
|
+
- Including explanatory text before or after the JSON
|
|
223
|
+
- Mismatched route `page` values and `pages` keys
|
|
224
|
+
- Using camelCase for page keys (use lowercase-hyphenated)
|
|
225
|
+
- Using lowercase for entity names (use PascalCase)
|
|
226
|
+
- Defining fields/validation that belongs in the types blueprint
|
|
227
|
+
- Forgetting `access` on routes
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://radish.dev/schemas/app.schema.json",
|
|
4
|
+
"title": "Radish App Blueprint",
|
|
5
|
+
"description": "Schema for defining application-level metadata, audience, workflows, features, and entity overview. This blueprint drives generation of types.yml, roles.yml, and UI layer blueprints.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"version",
|
|
9
|
+
"app"
|
|
10
|
+
],
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"properties": {
|
|
13
|
+
"version": {
|
|
14
|
+
"type": "integer",
|
|
15
|
+
"minimum": 1,
|
|
16
|
+
"description": "Blueprint spec version"
|
|
17
|
+
},
|
|
18
|
+
"app": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"description": "Core application metadata",
|
|
21
|
+
"required": [
|
|
22
|
+
"name",
|
|
23
|
+
"description"
|
|
24
|
+
],
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"properties": {
|
|
27
|
+
"name": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"minLength": 1,
|
|
30
|
+
"maxLength": 100,
|
|
31
|
+
"description": "Application name (PascalCase or camelCase, used for code generation)"
|
|
32
|
+
},
|
|
33
|
+
"displayName": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"maxLength": 200,
|
|
36
|
+
"description": "Human-readable display name"
|
|
37
|
+
},
|
|
38
|
+
"description": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"minLength": 1,
|
|
41
|
+
"maxLength": 2000,
|
|
42
|
+
"description": "Full description of the application purpose and functionality"
|
|
43
|
+
},
|
|
44
|
+
"version": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
47
|
+
"description": "Application version (semver format)"
|
|
48
|
+
},
|
|
49
|
+
"domain": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "Business domain (e.g., education, e-commerce, healthcare)"
|
|
52
|
+
},
|
|
53
|
+
"tags": {
|
|
54
|
+
"type": "array",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
},
|
|
58
|
+
"description": "Searchable tags for categorization"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"audience": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"description": "Target audience and user personas",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"properties": {
|
|
67
|
+
"primary": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Primary user persona"
|
|
70
|
+
},
|
|
71
|
+
"secondary": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Secondary user persona"
|
|
74
|
+
},
|
|
75
|
+
"admin": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Administrative user persona"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"workflows": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"description": "Core user workflows describing what users actually do",
|
|
84
|
+
"items": {
|
|
85
|
+
"type": "object",
|
|
86
|
+
"required": [
|
|
87
|
+
"name",
|
|
88
|
+
"actor",
|
|
89
|
+
"description"
|
|
90
|
+
],
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"properties": {
|
|
93
|
+
"name": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"minLength": 1,
|
|
96
|
+
"description": "Workflow name"
|
|
97
|
+
},
|
|
98
|
+
"actor": {
|
|
99
|
+
"type": "string",
|
|
100
|
+
"description": "User persona performing this workflow (e.g., student, instructor, admin)"
|
|
101
|
+
},
|
|
102
|
+
"description": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"minLength": 1,
|
|
105
|
+
"description": "Description of the workflow steps and goals"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"categories": {
|
|
111
|
+
"type": "array",
|
|
112
|
+
"description": "Content categories and taxonomy",
|
|
113
|
+
"items": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"required": [
|
|
116
|
+
"name"
|
|
117
|
+
],
|
|
118
|
+
"additionalProperties": false,
|
|
119
|
+
"properties": {
|
|
120
|
+
"name": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"minLength": 1,
|
|
123
|
+
"description": "Category name"
|
|
124
|
+
},
|
|
125
|
+
"subcategories": {
|
|
126
|
+
"type": "array",
|
|
127
|
+
"items": {
|
|
128
|
+
"type": "string"
|
|
129
|
+
},
|
|
130
|
+
"description": "Subcategory names"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"style": {
|
|
136
|
+
"type": "object",
|
|
137
|
+
"description": "Style and branding hints for UI generation",
|
|
138
|
+
"additionalProperties": false,
|
|
139
|
+
"properties": {
|
|
140
|
+
"theme": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"description": "Theme name or identifier"
|
|
143
|
+
},
|
|
144
|
+
"tone": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"description": "Brand tone (e.g., professional, playful, minimal)"
|
|
147
|
+
},
|
|
148
|
+
"palette": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"description": "Color palette description or key colors"
|
|
151
|
+
},
|
|
152
|
+
"typography": {
|
|
153
|
+
"type": "string",
|
|
154
|
+
"description": "Typography preferences"
|
|
155
|
+
},
|
|
156
|
+
"layout": {
|
|
157
|
+
"type": "string",
|
|
158
|
+
"description": "Layout style preferences"
|
|
159
|
+
},
|
|
160
|
+
"icons": {
|
|
161
|
+
"type": "string",
|
|
162
|
+
"description": "Icon style preferences"
|
|
163
|
+
},
|
|
164
|
+
"imagery": {
|
|
165
|
+
"type": "string",
|
|
166
|
+
"description": "Imagery and placeholder style"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"features": {
|
|
171
|
+
"type": "object",
|
|
172
|
+
"description": "Feature flags indicating what capabilities this app includes. Additional boolean flags are allowed for future features.",
|
|
173
|
+
"additionalProperties": {
|
|
174
|
+
"type": "boolean"
|
|
175
|
+
},
|
|
176
|
+
"properties": {
|
|
177
|
+
"auth": {
|
|
178
|
+
"type": "boolean",
|
|
179
|
+
"description": "Authentication system"
|
|
180
|
+
},
|
|
181
|
+
"roles": {
|
|
182
|
+
"type": "boolean",
|
|
183
|
+
"description": "Role-based access control"
|
|
184
|
+
},
|
|
185
|
+
"adminPanel": {
|
|
186
|
+
"type": "boolean",
|
|
187
|
+
"description": "Administrative panel"
|
|
188
|
+
},
|
|
189
|
+
"api": {
|
|
190
|
+
"type": "boolean",
|
|
191
|
+
"description": "REST API endpoints"
|
|
192
|
+
},
|
|
193
|
+
"search": {
|
|
194
|
+
"type": "boolean",
|
|
195
|
+
"description": "Search functionality"
|
|
196
|
+
},
|
|
197
|
+
"pagination": {
|
|
198
|
+
"type": "boolean",
|
|
199
|
+
"description": "Paginated lists"
|
|
200
|
+
},
|
|
201
|
+
"fileUploads": {
|
|
202
|
+
"type": "boolean",
|
|
203
|
+
"description": "File upload capability"
|
|
204
|
+
},
|
|
205
|
+
"notifications": {
|
|
206
|
+
"type": "boolean",
|
|
207
|
+
"description": "Notification system"
|
|
208
|
+
},
|
|
209
|
+
"analytics": {
|
|
210
|
+
"type": "boolean",
|
|
211
|
+
"description": "Analytics and reporting"
|
|
212
|
+
},
|
|
213
|
+
"scheduling": {
|
|
214
|
+
"type": "boolean",
|
|
215
|
+
"description": "Scheduling and calendar features"
|
|
216
|
+
},
|
|
217
|
+
"logging": {
|
|
218
|
+
"type": "boolean",
|
|
219
|
+
"description": "Application logging"
|
|
220
|
+
},
|
|
221
|
+
"cms": {
|
|
222
|
+
"type": "boolean",
|
|
223
|
+
"description": "CMS content management (ContentBlock, MediaAsset entities)"
|
|
224
|
+
},
|
|
225
|
+
"grants": {
|
|
226
|
+
"type": "boolean",
|
|
227
|
+
"description": "Grant-based access control (Grant entity for fine-grained permissions)"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"entityOverview": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"description": "High-level entity relationship summary grouped by domain concern. Drives types.yml generation.",
|
|
234
|
+
"patternProperties": {
|
|
235
|
+
"^[a-zA-Z][a-zA-Z0-9_]*$": {
|
|
236
|
+
"type": "array",
|
|
237
|
+
"description": "Group of related entities (e.g., core, engagement, community)",
|
|
238
|
+
"items": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"minProperties": 1,
|
|
241
|
+
"maxProperties": 1,
|
|
242
|
+
"patternProperties": {
|
|
243
|
+
"^[A-Z][A-Za-z0-9_]*$": {
|
|
244
|
+
"type": "string",
|
|
245
|
+
"description": "Entity name (PascalCase) mapped to a description of its purpose and relationships"
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
"additionalProperties": false
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"additionalProperties": false
|
|
253
|
+
},
|
|
254
|
+
"accessPatterns": {
|
|
255
|
+
"type": "object",
|
|
256
|
+
"description": "Access control patterns describing who can see/do what. Drives roles.yml generation.",
|
|
257
|
+
"patternProperties": {
|
|
258
|
+
"^[a-zA-Z][a-zA-Z0-9_]*$": {
|
|
259
|
+
"type": "array",
|
|
260
|
+
"description": "Access level (e.g., public, authenticated, instructor, admin) mapped to permitted actions",
|
|
261
|
+
"items": {
|
|
262
|
+
"type": "string"
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"additionalProperties": false
|
|
267
|
+
},
|
|
268
|
+
"database": {
|
|
269
|
+
"type": "object",
|
|
270
|
+
"description": "Database configuration",
|
|
271
|
+
"additionalProperties": false,
|
|
272
|
+
"properties": {
|
|
273
|
+
"type": {
|
|
274
|
+
"type": "string",
|
|
275
|
+
"enum": [
|
|
276
|
+
"mongodb",
|
|
277
|
+
"postgresql",
|
|
278
|
+
"mysql"
|
|
279
|
+
],
|
|
280
|
+
"description": "Database engine"
|
|
281
|
+
},
|
|
282
|
+
"name": {
|
|
283
|
+
"type": "string",
|
|
284
|
+
"description": "Database name"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|