odac 1.4.0 → 1.4.2

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.
Files changed (96) hide show
  1. package/.agent/rules/memory.md +8 -0
  2. package/.github/workflows/release.yml +1 -1
  3. package/.releaserc.js +9 -2
  4. package/CHANGELOG.md +61 -0
  5. package/README.md +10 -0
  6. package/bin/odac.js +193 -2
  7. package/client/odac.js +32 -13
  8. package/docs/ai/skills/SKILL.md +4 -3
  9. package/docs/ai/skills/backend/authentication.md +7 -0
  10. package/docs/ai/skills/backend/config.md +7 -0
  11. package/docs/ai/skills/backend/controllers.md +7 -0
  12. package/docs/ai/skills/backend/cron.md +9 -2
  13. package/docs/ai/skills/backend/database.md +37 -2
  14. package/docs/ai/skills/backend/forms.md +112 -11
  15. package/docs/ai/skills/backend/ipc.md +7 -0
  16. package/docs/ai/skills/backend/mail.md +7 -0
  17. package/docs/ai/skills/backend/migrations.md +86 -0
  18. package/docs/ai/skills/backend/request_response.md +7 -0
  19. package/docs/ai/skills/backend/routing.md +7 -0
  20. package/docs/ai/skills/backend/storage.md +7 -0
  21. package/docs/ai/skills/backend/streaming.md +7 -0
  22. package/docs/ai/skills/backend/structure.md +8 -1
  23. package/docs/ai/skills/backend/translations.md +7 -0
  24. package/docs/ai/skills/backend/utilities.md +7 -0
  25. package/docs/ai/skills/backend/validation.md +138 -31
  26. package/docs/ai/skills/backend/views.md +7 -0
  27. package/docs/ai/skills/frontend/core.md +7 -0
  28. package/docs/ai/skills/frontend/forms.md +48 -13
  29. package/docs/ai/skills/frontend/navigation.md +7 -0
  30. package/docs/ai/skills/frontend/realtime.md +7 -0
  31. package/docs/backend/08-database/02-basics.md +49 -9
  32. package/docs/backend/08-database/04-migrations.md +259 -37
  33. package/package.json +1 -1
  34. package/src/Auth.js +82 -43
  35. package/src/Config.js +1 -1
  36. package/src/Database/ConnectionFactory.js +70 -0
  37. package/src/Database/Migration.js +1228 -0
  38. package/src/Database/nanoid.js +30 -0
  39. package/src/Database.js +157 -46
  40. package/src/Ipc.js +37 -0
  41. package/src/Odac.js +1 -1
  42. package/src/Route/Cron.js +11 -0
  43. package/src/Route.js +8 -0
  44. package/src/Server.js +77 -23
  45. package/src/Storage.js +15 -1
  46. package/src/Validator.js +22 -20
  47. package/template/schema/users.js +23 -0
  48. package/test/{Auth.test.js → Auth/check.test.js} +153 -6
  49. package/test/Client/data.test.js +91 -0
  50. package/test/Client/get.test.js +90 -0
  51. package/test/Client/storage.test.js +87 -0
  52. package/test/Client/token.test.js +82 -0
  53. package/test/Client/ws.test.js +86 -0
  54. package/test/Config/deepMerge.test.js +14 -0
  55. package/test/Config/init.test.js +66 -0
  56. package/test/Config/interpolate.test.js +35 -0
  57. package/test/Database/ConnectionFactory/buildConnectionConfig.test.js +13 -0
  58. package/test/Database/ConnectionFactory/buildConnections.test.js +31 -0
  59. package/test/Database/ConnectionFactory/resolveClient.test.js +12 -0
  60. package/test/Database/Migration/migrate_column.test.js +52 -0
  61. package/test/Database/Migration/migrate_files.test.js +70 -0
  62. package/test/Database/Migration/migrate_index.test.js +89 -0
  63. package/test/Database/Migration/migrate_nanoid.test.js +160 -0
  64. package/test/Database/Migration/migrate_seed.test.js +77 -0
  65. package/test/Database/Migration/migrate_table.test.js +88 -0
  66. package/test/Database/Migration/rollback.test.js +61 -0
  67. package/test/Database/Migration/snapshot.test.js +38 -0
  68. package/test/Database/Migration/status.test.js +41 -0
  69. package/test/Database/autoNanoid.test.js +215 -0
  70. package/test/Database/nanoid.test.js +19 -0
  71. package/test/Lang/constructor.test.js +25 -0
  72. package/test/Lang/get.test.js +65 -0
  73. package/test/Lang/set.test.js +49 -0
  74. package/test/Odac/init.test.js +42 -0
  75. package/test/Odac/instance.test.js +58 -0
  76. package/test/Route/{Middleware.test.js → Middleware/chaining.test.js} +5 -29
  77. package/test/Route/Middleware/use.test.js +35 -0
  78. package/test/{Route.test.js → Route/check.test.js} +4 -55
  79. package/test/Route/set.test.js +52 -0
  80. package/test/Route/ws.test.js +23 -0
  81. package/test/View/EarlyHints/cache.test.js +32 -0
  82. package/test/View/EarlyHints/extractFromHtml.test.js +143 -0
  83. package/test/View/EarlyHints/formatLinkHeader.test.js +33 -0
  84. package/test/View/EarlyHints/send.test.js +99 -0
  85. package/test/View/{Form.test.js → Form/generateFieldHtml.test.js} +2 -2
  86. package/test/View/constructor.test.js +22 -0
  87. package/test/View/print.test.js +19 -0
  88. package/test/WebSocket/Client/limits.test.js +55 -0
  89. package/test/WebSocket/Server/broadcast.test.js +33 -0
  90. package/test/WebSocket/Server/route.test.js +37 -0
  91. package/test/Client.test.js +0 -197
  92. package/test/Config.test.js +0 -112
  93. package/test/Lang.test.js +0 -92
  94. package/test/Odac.test.js +0 -88
  95. package/test/View/EarlyHints.test.js +0 -282
  96. package/test/WebSocket.test.js +0 -238
@@ -1,19 +1,120 @@
1
+ ---
2
+ name: backend-forms-validation-skill
3
+ description: Practical ODAC form usage patterns for register/login, magic-login, custom actions, and automatic database insert.
4
+ metadata:
5
+ tags: backend, forms, validation, register, login, magic-login, request-processing
6
+ ---
7
+
1
8
  # Backend Forms & Validation Skill
2
9
 
3
- Processing form data securely and validating inputs.
10
+ ODAC forms for validation, authentication flows, and safe request handling.
4
11
 
5
12
  ## Rules
6
- 1. **Validator**: Always use `Odac.Validator` for input.
7
- 2. **Auto-save**: Use `Odac.Db.table().save(Odac.Request.post())` for quick inserts.
8
- 3. **CSRF**: Ensure `{{ TOKEN }}` is in your HTML forms.
13
+ 1. **Use ODAC form tags**: Prefer `<odac:register>`, `<odac:login>`, `<odac:magic-login>`, `<odac:form>` instead of manual raw form handlers.
14
+ 2. **Do not add manual hidden security fields**: Keep forms clean and use ODAC defaults.
15
+ 3. **Validation in template**: Define rules with `<odac:validate rule="..." message="..."/>`; they become both frontend HTML constraints and backend validator checks.
16
+ 4. **Server-side enrichment**: Use `<odac:set>` for trusted fields (`compute`, `value`, `callback`, `if-empty`) instead of taking these values from user input.
17
+ 5. **Action vs table**: In `<odac:form>`, use `table="..."` for automatic insert or `action="Class.method"` for custom business logic.
18
+
19
+ ## Form Type Variants
20
+
21
+ ### 1) Register Form
22
+ ```html
23
+ <odac:register redirect="/dashboard" autologin="true">
24
+ <odac:input name="email" type="email" label="Email">
25
+ <odac:validate rule="required|email" message="Valid email required"/>
26
+ </odac:input>
27
+
28
+ <odac:input name="password" type="password" label="Password">
29
+ <odac:validate rule="required|minlen:8" message="Min 8 chars"/>
30
+ </odac:input>
31
+
32
+ <odac:set name="created_at" compute="now"/>
33
+ <odac:submit text="Register" loading="Processing..."/>
34
+ </odac:register>
35
+ ```
36
+
37
+ ### 2) Login Form
38
+ ```html
39
+ <odac:login redirect="/panel">
40
+ <odac:input name="email" type="email" label="Email">
41
+ <odac:validate rule="required|email" message="Email required"/>
42
+ </odac:input>
43
+
44
+ <odac:input name="password" type="password" label="Password">
45
+ <odac:validate rule="required" message="Password required"/>
46
+ </odac:input>
47
+
48
+ <odac:submit text="Login" loading="Logging in..."/>
49
+ </odac:login>
50
+ ```
51
+
52
+ ### 3) Magic Login Form
53
+ ```html
54
+ <odac:magic-login redirect="/dashboard" email-label="Work Email" submit-text="Send Link" />
55
+ ```
56
+
57
+ ```html
58
+ <odac:magic-login redirect="/dashboard">
59
+ <odac:input name="email" type="email" label="Email">
60
+ <odac:validate rule="required|email" message="Valid email required"/>
61
+ </odac:input>
62
+ <odac:submit text="Send Magic Link" loading="Sending..."/>
63
+ </odac:magic-login>
64
+ ```
65
+
66
+ ### 4) Custom Form with Automatic DB Insert
67
+ ```html
68
+ <odac:form table="waitlist" redirect="/" success="Thank you!" clear="true">
69
+ <odac:input name="email" type="email" label="Email">
70
+ <odac:validate rule="required|email|unique" message="Email already exists"/>
71
+ </odac:input>
72
+
73
+ <odac:set name="created_at" compute="now"/>
74
+ <odac:set name="ip" compute="ip"/>
75
+ <odac:submit text="Join" loading="Joining..."/>
76
+ </odac:form>
77
+ ```
78
+
79
+ ### 5) Custom Form with Controller Action
80
+ ```html
81
+ <odac:form action="Contact.submit" clear="false">
82
+ <odac:input name="subject" type="text" label="Subject">
83
+ <odac:validate rule="required|minlen:3" message="Subject is too short"/>
84
+ </odac:input>
85
+ <odac:submit text="Send" loading="Sending..."/>
86
+ </odac:form>
87
+ ```
9
88
 
10
- ## Patterns
11
89
  ```javascript
12
- // Validation
13
- const check = Odac.Validator.run(Odac.Request.post(), {
14
- email: 'required|email',
15
- password: 'required|min:8'
16
- });
90
+ module.exports = class Contact {
91
+ constructor(Odac) {
92
+ this.Odac = Odac
93
+ }
94
+
95
+ async submit(form) {
96
+ const data = form.data
97
+ if (!data.subject) return form.error('subject', 'Subject required')
98
+ return form.success('Message sent', '/thank-you')
99
+ }
100
+ }
101
+ ```
17
102
 
18
- if (check.failed()) return Odac.Request.error(check.errors());
103
+ ## Field-Level Variants
104
+ - **Input types**: `text`, `email`, `password`, `number`, `url`, `textarea`, `checkbox`.
105
+ - **Validation mapping**: `required|minlen|maxlen|min|max|alpha|alphanumeric|numeric|email|url|accepted`.
106
+ - **Pass-through attrs**: Unrecognized `<odac:input ...>` attributes are preserved into generated HTML input/textarea.
107
+ - **Skip persistence**: Use `skip` on `<odac:input>` to validate a field but exclude it from final payload.
108
+ - **Unique shorthand**: `unique` attribute on `<odac:input>` enables auth-register uniqueness list.
109
+
110
+ ## Patterns
111
+ ```javascript
112
+ // Access validated data in action-driven custom form
113
+ Odac.Route.class.post('/contact', class Contact {
114
+ async submit(form) {
115
+ const {email, message} = form.data
116
+ if (!email || !message) return form.error('_odac_form', 'Missing input')
117
+ return form.success('Saved successfully')
118
+ }
119
+ })
19
120
  ```
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-ipc-skill
3
+ description: ODAC inter-process communication guidance for memory and Redis drivers, shared state, and distributed coordination.
4
+ metadata:
5
+ tags: backend, ipc, redis, cluster, distributed-state, synchronization
6
+ ---
7
+
1
8
  # Backend IPC (Inter-Process Communication) Skill
2
9
 
3
10
  ODAC provides a built-in IPC system to share data and sync states across application workers or multiple servers.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-mail-skill
3
+ description: Transactional email integration patterns in ODAC using fluent mail APIs, templating, and transport configuration.
4
+ metadata:
5
+ tags: backend, mail, smtp, transactional-email, templating, notifications
6
+ ---
7
+
1
8
  # Backend Mail Skill
2
9
 
3
10
  Sending transactional emails using the fluent `Odac.Mail` service.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: backend-migrations-skill
3
+ description: Schema-first ODAC migration strategy for deterministic database evolution, index sync, and cluster-safe execution.
4
+ metadata:
5
+ tags: backend, migrations, schema, database-evolution, indexes, cluster-safety
6
+ ---
7
+
8
+ # Backend Migrations Skill
9
+
10
+ Schema-first, zero-config migration strategy for ODAC.
11
+
12
+ ## Architectural Approach
13
+ ODAC migrations are **declarative**. The `schema/` directory is the single source of truth for final DB state. The migration engine diffs desired schema vs current DB and applies create/alter/drop operations automatically.
14
+
15
+ ## Core Rules
16
+ 1. **Source of Truth**: Always update `schema/*.js` files, not historical migration chains, for structural changes.
17
+ 2. **Auto Execution**: Migrations run automatically during app startup via `Database.init()`.
18
+ 3. **Cluster Safety**: Auto-migration runs only on `cluster.isPrimary` to prevent race conditions.
19
+ 4. **Index Sync**: Define indexes in schema; engine adds/removes them automatically.
20
+ 5. **Drop Behavior**: If a column/index is removed from schema, it is removed from DB on next startup.
21
+ 6. **Seeds**: Use `seed` + `seedKey` for idempotent reference data.
22
+ 7. **NanoID Columns**: `type: 'nanoid'` maps to string columns and missing values are auto-generated on insert/seed.
23
+ 8. **Data Transformations**: Use imperative files under `migration/` only for one-time data migration logic.
24
+
25
+ ## Reference Patterns
26
+ ### 1. Schema File (Final State)
27
+ ```javascript
28
+ // schema/users.js
29
+ 'use strict'
30
+
31
+ module.exports = {
32
+ columns: {
33
+ id: {type: 'nanoid', primary: true},
34
+ email: {type: 'string', length: 255, nullable: false},
35
+ role: {type: 'enum', values: ['admin', 'user'], default: 'user'},
36
+ timestamps: {type: 'timestamps'}
37
+ },
38
+ indexes: [
39
+ {columns: ['email'], unique: true}
40
+ ],
41
+ seed: [
42
+ {email: 'admin@example.com', role: 'admin'}
43
+ ],
44
+ seedKey: 'email'
45
+ }
46
+ ```
47
+
48
+ ### NanoID Notes
49
+ - `length` can be customized: `{type: 'nanoid', length: 12, primary: true}`.
50
+ - If seed rows omit the nanoid field, ODAC fills it automatically.
51
+ - If seed rows provide an explicit nanoid value, ODAC keeps it unchanged.
52
+
53
+ ### 2. Multi-Database Layout
54
+ ```
55
+ schema/
56
+ users.js # default DB
57
+ analytics/
58
+ events.js # analytics DB
59
+ ```
60
+
61
+ ### 3. Imperative Data Migration (One-Time)
62
+ ```javascript
63
+ // migration/20260225_001_backfill_roles.js
64
+ module.exports = {
65
+ async up(db) {
66
+ await db('users').whereNull('role').update({role: 'user'})
67
+ },
68
+ async down(db) {
69
+ await db('users').where('role', 'user').update({role: null})
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### 4. CLI Operations
75
+ ```bash
76
+ npx odac migrate
77
+ npx odac migrate:status
78
+ npx odac migrate:rollback
79
+ npx odac migrate:snapshot
80
+ ```
81
+
82
+ ## Performance and Safety Notes
83
+ - Keep schema declarations deterministic and minimal.
84
+ - Prefer additive changes; drops are destructive and should be intentional.
85
+ - Ensure high-cardinality lookup columns are indexed in schema definitions.
86
+ - For very large tables, plan expensive column rewrites as dedicated data migrations.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-request-response-skill
3
+ description: ODAC request parsing and response composition patterns for consistent, secure, and predictable API behavior.
4
+ metadata:
5
+ tags: backend, request, response, headers, status-codes, json, api
6
+ ---
7
+
1
8
  # Backend Request & Response Skill
2
9
 
3
10
  Handling incoming data and sending structured responses.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-routing-middleware-skill
3
+ description: High-performance ODAC routing and middleware orchestration for secure request pipelines and scalable URL mapping.
4
+ metadata:
5
+ tags: backend, routing, middleware, pipeline, auth, performance, url-matching
6
+ ---
7
+
1
8
  # Backend Routing & Middleware Skill
2
9
 
3
10
  Routing manages the request pipeline, directing URLs to controllers while applying security and business logic via middlewares.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-persistent-storage-skill
3
+ description: Embedded ODAC storage usage patterns with LMDB for sub-millisecond key-value persistence across workers.
4
+ metadata:
5
+ tags: backend, storage, lmdb, key-value, persistence, high-performance
6
+ ---
7
+
1
8
  # Backend Persistent Storage Skill
2
9
 
3
10
  ODAC provides a high-performance, embedded key-value store using LMDB, exposed via `Odac.Storage`.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-streaming-sse-skill
3
+ description: Server-Sent Events streaming patterns in ODAC for realtime one-way updates with safe connection lifecycle management.
4
+ metadata:
5
+ tags: backend, streaming, sse, realtime, event-stream, connection-lifecycle
6
+ ---
7
+
1
8
  # Backend Streaming API Skill
2
9
 
3
10
  Real-time data streaming using Server-Sent Events (SSE).
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-structure-services-skill
3
+ description: ODAC project organization rules for directory structure, service classes, and request-scoped architecture.
4
+ metadata:
5
+ tags: backend, structure, services, architecture, request-scope, organization
6
+ ---
7
+
1
8
  # Backend Structure & Services Skill
2
9
 
3
10
  ODAC follows a strictly organized directory structure and focuses on request-scoped architecture. This skill explains how to organize code and use Service Classes.
@@ -31,7 +38,7 @@ class User {
31
38
 
32
39
  async getProfile(id) {
33
40
  // Access database or auth via this.Odac
34
- return await this.Odac.Db.table('users').where('id', id).first();
41
+ return await this.Odac.DB.table('users').where('id', id).first();
35
42
  }
36
43
  }
37
44
  module.exports = User;
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-translations-i18n-skill
3
+ description: Internationalization patterns in ODAC for locale files, placeholders, and multilingual rendering workflows.
4
+ metadata:
5
+ tags: backend, i18n, translations, locale, placeholders, multilingual
6
+ ---
7
+
1
8
  # Backend Translations (i18n) Skill
2
9
 
3
10
  ODAC provides built-in support for internationalization, allowing for easy multi-language application development.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-utilities-skill
3
+ description: Practical ODAC utility patterns for string processing, hashing, encryption, and request flow control.
4
+ metadata:
5
+ tags: backend, utilities, strings, hashing, encryption, flow-control
6
+ ---
7
+
1
8
  # Backend Utilities Skill
2
9
 
3
10
  String manipulation, hashing, and flow control.
@@ -1,53 +1,160 @@
1
- # Backend Validation Skill
1
+ ---
2
+ name: backend-validation-skill
3
+ description: Detailed ODAC Validator usage for request validation, security checks, brute-force protection, and consistent API responses.
4
+ metadata:
5
+ tags: backend, validation, fluent-api, input-security, brute-force, error-handling
6
+ ---
2
7
 
3
- The `Validator` service provides a fluent, chainable API for securing user input and enforcing business rules.
8
+ # Backend Validation Skill
4
9
 
5
- ## Architectural Approach
6
- Validation should happen as early as possible in the request lifecycle. The `Validator` service handles automatic error formatting and frontend integration.
10
+ ODAC validation should be centralized with the fluent `Validator` API and returned in framework-standard result format.
7
11
 
8
12
  ## Core Rules
9
- 1. **Chaining**: Use the fluent API: `.post(key).check(rules).message(msg)`.
10
- 2. **Brute Force**: Protect sensitive endpoints with `.brute(attempts)`.
11
- 3. **Automatic Errors**: Use `await validator.error()` to check status and `await validator.result()` to return standardized JSON.
12
- 4. **Inverse Rules**: Use `!` to invert any rule (e.g., `!required`).
13
+ 1. **Create validator per request**: Use `const validator = Odac.validator()`.
14
+ 2. **Fail fast**: Run all checks, then immediately return on `await validator.error()`.
15
+ 3. **Field-first messages**: Assign a specific `.message(...)` per check chain.
16
+ 4. **Use standard result shape**: Return `await validator.result('Validation failed')` for errors.
17
+ 5. **Protect sensitive flows**: Add `await validator.brute(n)` on login/reset/auth endpoints.
18
+
19
+ ## Minimal Flow
20
+ ```javascript
21
+ module.exports = async Odac => {
22
+ const validator = Odac.validator()
23
+
24
+ validator.post('email').check('required|email').message('Valid email required')
25
+ validator.post('password').check('required|minlen:8').message('Password must be at least 8 characters')
26
+
27
+ if (await validator.error()) {
28
+ await validator.brute(5)
29
+ return await validator.result('Validation failed')
30
+ }
31
+
32
+ return await validator.success({ok: true})
33
+ }
34
+ ```
35
+
36
+ ## API Surface
37
+ - `post(key)`: Validate POST payload field.
38
+ - `get(key)`: Validate querystring field.
39
+ - `var(name, value)`: Validate computed/custom value.
40
+ - `file(name)`: Validate uploaded file object.
41
+ - `check(rules | boolean)`: Apply pipe rules or direct boolean validation.
42
+ - `message(text)`: Set message for the latest check on current field.
43
+ - `error()`: Runs validation and returns `true` if any error exists.
44
+ - `result(message?, data?)`: Returns ODAC-standard response object.
45
+ - `success(dataOrMessage?)`: Convenience wrapper for success payload.
46
+ - `brute(maxAttempts = 5)`: Tracks failed attempts per hour/page/ip.
47
+
48
+ ## Rule Catalog
49
+
50
+ ### Type & format rules
51
+ - `required`, `accepted`
52
+ - `numeric`, `float`
53
+ - `alpha`, `alphaspace`, `alphanumeric`, `alphanumericspace`, `username`
54
+ - `email`, `ip`, `mac`, `domain`, `url`
55
+ - `array`, `date`, `xss`
56
+
57
+ ### Length & value rules
58
+ - `len:X`, `minlen:X`, `maxlen:X`
59
+ - `min:X`, `max:X`
60
+ - `equal:value`, `not:value`
61
+ - `same:field`, `different:field`
62
+
63
+ ### String/date matching rules
64
+ - `in:substring`, `notin:substring`
65
+ - `regex:pattern`
66
+ - `mindate:YYYY-MM-DD`, `maxdate:YYYY-MM-DD`
67
+
68
+ ### Auth/security rules
69
+ - `usercheck`: Must be authenticated.
70
+ - `user:field`: Input must match authenticated user field.
71
+ - `disposable`: Email must be disposable.
72
+ - `!disposable`: Email must not be disposable.
73
+
74
+ ### Inverse rules
75
+ - Prefix any rule with `!` to invert: `!required`, `!email`, `!equal:admin`.
13
76
 
14
77
  ## Reference Patterns
15
78
 
16
- ### 1. Standard Validation Chaining
79
+ ### 1) Multi-check per field with specific errors
17
80
  ```javascript
18
- module.exports = async function (Odac) {
19
- const validator = Odac.Validator;
81
+ module.exports = async Odac => {
82
+ const validator = Odac.validator()
20
83
 
21
84
  validator
22
- .post('email').check('required|email').message('Valid email required')
23
- .post('password').check('required|minlen:8').message('Password too short');
85
+ .post('password')
86
+ .check('required').message('Password is required')
87
+ .check('minlen:8').message('Minimum 8 characters')
88
+ .check('regex:[A-Z]').message('At least one uppercase letter')
89
+ .check('regex:[0-9]').message('At least one number')
24
90
 
25
91
  if (await validator.error()) {
26
- return validator.result('Please fix input errors');
92
+ return await validator.result('Please fix input errors')
27
93
  }
28
94
 
29
- // Proceed with validated data
30
- return validator.success('Success');
31
- };
95
+ return await validator.success('Success')
96
+ }
97
+ ```
98
+
99
+ ### 2) GET + POST + VAR together
100
+ ```javascript
101
+ module.exports = async Odac => {
102
+ const validator = Odac.validator()
103
+ const plan = await Odac.request('plan')
104
+
105
+ validator.get('page').check('numeric|min:1').message('Invalid page')
106
+ validator.post('email').check('required|email|!disposable').message('Corporate email required')
107
+ validator.var('plan', plan).check('in:pro').message('Only pro plan is allowed')
108
+
109
+ if (await validator.error()) return await validator.result('Validation failed')
110
+ return await validator.success({ok: true})
111
+ }
32
112
  ```
33
113
 
34
- ### 2. Custom Variable and Security Validation
114
+ ### 3) Boolean check for business rules
35
115
  ```javascript
36
- validator.var('age', userAge).check('numeric|min:18').message('Must be 18+');
116
+ module.exports = async Odac => {
117
+ const validator = Odac.validator()
118
+ const canPublish = await somePermissionCheck(Odac)
119
+
120
+ validator.post('title').check('required').message('Title required')
121
+ validator.var('permission', null).check(canPublish).message('No publish permission')
122
+
123
+ if (await validator.error()) return await validator.result('Validation failed')
124
+ return await validator.success('Published')
125
+ }
126
+ ```
127
+
128
+ ### 4) Brute-force on auth endpoint
129
+ ```javascript
130
+ module.exports = async Odac => {
131
+ const validator = Odac.validator()
132
+
133
+ validator.post('email').check('required|email').message('Email required')
134
+ validator.post('password').check('required').message('Password required')
135
+
136
+ if (await validator.error()) {
137
+ await validator.brute(5)
138
+ return await validator.result('Login failed')
139
+ }
37
140
 
38
- // Security checks
39
- validator.post('bio').check('xss').message('Malicious HTML detected');
40
- validator.var('auth', null).check('usercheck').message('Authentication required');
141
+ return await validator.success('OK')
142
+ }
41
143
  ```
42
144
 
43
- ### 3. Common Rules Reference
44
- - `required`, `email`, `numeric`, `username`, `url`, `ip`, `json`.
45
- - `len:X`, `minlen:X`, `maxlen:X`.
46
- - `mindate:YYYY-MM-DD`, `maxdate:YYYY-MM-DD`.
47
- - `regex:pattern`, `same:field`, `different:field`.
48
- - `!disposable`: Blocks temporary email providers.
145
+ ## Response Contract
146
+ - **Success**:
147
+ - `result.success: true`
148
+ - optional `result.message`
149
+ - optional `data`
150
+ - **Failure**:
151
+ - `result.success: false`
152
+ - `errors.{field}` map
153
+ - global errors may use `errors._odac_form`
49
154
 
50
155
  ## Best Practices
51
- - **Specific Messages**: Provide helpful error messages that guide the user.
52
- - **Security First**: Use the `xss` rule for any user-generated content that will be rendered later.
53
- - **Fail Fast**: Return the validation result immediately if `validator.error()` is true.
156
+ - Keep validation at route/controller entry; do not defer to deep service layers.
157
+ - Use separate `check()` calls when you need rule-specific messages.
158
+ - Prefer `var()` for derived values instead of re-reading mutable request state.
159
+ - Use `xss` for text fields that can later be rendered in HTML.
160
+ - Always combine auth endpoints with `brute()` to reduce credential-stuffing risk.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: backend-views-templates-skill
3
+ description: ODAC server-side rendering guidelines for template performance, skeleton layouts, and safe output rendering.
4
+ metadata:
5
+ tags: backend, views, templates, ssr, xss-protection, skeleton, rendering
6
+ ---
7
+
1
8
  # Backend Views & Templates Skill
2
9
 
3
10
  High-performance server-side rendering using ODAC's optimized template engine.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: frontend-core-skill
3
+ description: Core ODAC frontend architecture patterns based on actions, lifecycle hooks, and event-driven UI behavior.
4
+ metadata:
5
+ tags: frontend, odac-js, actions, lifecycle, events, ui-architecture
6
+ ---
7
+
1
8
  # Frontend Core Skill
2
9
 
3
10
  The foundational principles of the `odac.js` library for building reactive and interactive user interfaces.
@@ -1,21 +1,56 @@
1
+ ---
2
+ name: frontend-forms-api-skill
3
+ description: odac.js form submission patterns for parser-generated ODAC forms and predictable AJAX request handling.
4
+ metadata:
5
+ tags: frontend, forms, ajax, odac-form, register, login, magic-login
6
+ ---
7
+
1
8
  # Frontend Forms & API Skill
2
9
 
3
- Handling AJAX form submissions and API requests.
10
+ Handling ODAC AJAX form submissions generated from server-side form parsing.
4
11
 
5
12
  ## Rules
6
- 1. **Forms**: Use `odac.form('#id', callback)` for AJAX submission.
7
- 2. **Requests**: Use `odac.get()` and `odac.post()` for manual requests.
8
- 3. **Realtime**: Handle WebSocket events using Hub structures in `Odac.action()`.
13
+ 1. **Bind by form selector**: Use `Odac.form({ form: 'selector' }, callback)` or short form `Odac.form('selector', callback)`.
14
+ 2. **Leverage parser-generated forms**: `odac-register`, `odac-login`, `odac-magic-login`, and `odac-custom-form` are all auto-bound on page load and after every AJAX navigation.
15
+ 3. **Expect JSON result shape**: Handle `result.success`, `result.message`, `result.redirect`, and `errors` in callback.
16
+ 4. **Message/clear control**: Use `messages` and `clear` options for UX behavior.
9
17
 
10
18
  ## Patterns
11
19
  ```javascript
12
- // Form with automatic validation feedback
13
- odac.form('#my-form', (res) => {
14
- if(res.success) odac.visit('/done');
15
- });
16
-
17
- // Simple API Check
18
- odac.get('/api/status', (data) => {
19
- console.log('Status:', data);
20
- });
20
+ // 1) Bind a parsed custom form
21
+ Odac.form('form[data-odac-form]')
22
+
23
+ // 2) Bind parsed register/login forms explicitly (optional)
24
+ Odac.form('form[data-odac-register]')
25
+ Odac.form('form[data-odac-login]')
26
+
27
+ // 3) Bind parsed magic-login form manually
28
+ Odac.form('form[data-odac-magic-login]', response => {
29
+ if (response?.result?.success && !response.result.redirect) {
30
+ const info = document.querySelector('[data-status]')
31
+ if (info) info.textContent = response.result.message
32
+ }
33
+ })
34
+
35
+ // 4) Advanced options: disable auto clear and hide success messages
36
+ Odac.form(
37
+ {form: 'form[data-odac-form]', clear: false, messages: ['error']},
38
+ response => {
39
+ if (response?.result?.success && response.result.redirect) {
40
+ window.location.href = response.result.redirect
41
+ }
42
+ }
43
+ )
44
+
45
+ // 5) Manual GET request helper
46
+ Odac.get('/api/status', data => {
47
+ const status = document.querySelector('[data-api-status]')
48
+ if (status) status.textContent = String(data?.status ?? '')
49
+ })
21
50
  ```
51
+
52
+ ## Response Handling Contract
53
+ - **Success**: `response.result.success === true`
54
+ - **Redirect**: `response.result.redirect` exists when server wants navigation
55
+ - **Form errors**: `response.errors.{fieldName}` maps to `odac-form-error="fieldName"`
56
+ - **Global form error**: `response.errors._odac_form`
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: frontend-navigation-spa-skill
3
+ description: Single-page navigation patterns in odac.js for smooth transitions, route control, and lifecycle-safe execution.
4
+ metadata:
5
+ tags: frontend, navigation, spa, ajax-navigation, page-lifecycle, transitions
6
+ ---
7
+
1
8
  # Frontend Navigation & SPA Skill
2
9
 
3
10
  Smooth transitions and single-page application behavior using `odac.js`.
@@ -1,3 +1,10 @@
1
+ ---
2
+ name: frontend-realtime-websocket-skill
3
+ description: Realtime frontend communication patterns in odac.js using shared WebSockets, SSE, and resilient reconnect behavior.
4
+ metadata:
5
+ tags: frontend, realtime, websocket, sse, sharedworker, auto-reconnect
6
+ ---
7
+
1
8
  # Frontend Realtime & WebSocket Skill
2
9
 
3
10
  Real-time bidirectional communication and server-sent events with high efficiency.