원클릭으로
grain-schema
Define Malli schemas for commands, events, and queries using defschemas
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Define Malli schemas for commands, events, and queries using defschemas
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | grain-schema |
| description | Define Malli schemas for commands, events, and queries using defschemas |
(ns cjbarre.grain-todo-list.service.todo-list-service.schemas
(:require [ai.obney.grain.schema-util.interface :refer [defschemas]]))
Use defschemas to register named Malli schemas:
(defschemas schema-group-name
{:schema-key schema-definition
:another-key another-definition})
This repo groups schemas into named defschemas groups: common-schemas,
event-schemas, command-schemas, query-schemas, and read-model-schemas.
Naming: :namespace/verb (verb form)
(defschemas command-schemas
{;; Create command
:todo/capture-task
[:map
[:title ::non-blank-string]
[:task-id {:optional true} :uuid]
[:project-id {:optional true} :uuid]
[:order {:optional true} ::order]]
;; Update command
:todo/rename-task
[:map
[:task-id :uuid]
[:title ::non-blank-string]]
;; Action command
:todo/start-weekly-review
[:map
[:review-id {:optional true} :uuid]]})
Naming: :namespace/entity-past-tense (what happened)
(defschemas event-schemas
{;; Created event
:todo/task-captured
[:map
[:user-id :uuid]
[:task-id :uuid]
[:title ::non-blank-string]
[:status ::task-status]
[:order ::order]
[:project-id {:optional true} :uuid]]
;; Renamed event
:todo/task-renamed
[:map
[:user-id :uuid]
[:task-id :uuid]
[:title ::non-blank-string]]
;; Action completed event
:todo/weekly-review-started
[:map
[:user-id :uuid]
[:review-id :uuid]
[:started-at :time/offset-date-time]]})
Naming: :namespace/query-name (the page or data being requested)
(defschemas query-schemas
{:todo/home-page [:map]
:todo/tasks-page [:map]
:todo/task-page [:map [:task-id :uuid]]
:todo/projects-page [:map]
:todo/project-page [:map [:project-id :uuid]]})
Read-model state schemas are declared in their own read-model-schemas
group. The schema describes the shape of the projected state (typically a map
keyed by entity id):
(defschemas read-model-schemas
{:todo/tasks [:map-of :uuid ::task]
:todo/projects [:map-of :uuid ::project]})
:string ;; String
:int ;; Integer
:double ;; Float
:boolean ;; Boolean
:uuid ;; UUID
:keyword ;; Keyword
:any ;; Any value
[:enum :a :b :c] ;; Enum
[:set :string] ;; Set of strings
[:vector :uuid] ;; Vector of UUIDs
[:map-of :keyword :any] ;; Map with keyword keys
[:map ;; Map with specific keys
[:required-key :string]
[:optional-key {:optional true} :int]]
[:re #"^[a-z]+$"] ;; Regex pattern
(defschemas custom-types
{:email [:re #"^[^@\s]+@[^@\s]+\.[^@\s]+$"]
:phone [:re #"^\d{10,15}$"]
:encrypted [:map
[:ciphertext :string]
[:encrypted-key :string]
[:iv :string]]})
Common schemas can be referenced by qualified keyword (::name) from other
groups. In this repo the common-schemas group holds these reusable pieces:
(defschemas common-schemas
{::non-blank-string [:fn {:error/message "Must not be blank"} non-blank-string?]
::task-status [:enum :active :completed :canceled :archived]
::order number?
::task [:map
[:user-id :uuid]
[:task-id :uuid]
[:title ::non-blank-string]
[:status ::task-status]
[:order ::order]
[:project-id {:optional true} :uuid]]})
(defschemas event-schemas
{:todo/task-captured ::task}) ;; reuse the ::task shape directly
common-schemas, event-schemas, command-schemas, query-schemas, read-model-schemas:namespace/verb (capture, rename, complete, start, etc.):namespace/entity-past-tense (captured, renamed, started):namespace/...-page (one per page/screen){:optional true} for optional fieldscommon-schemas and reference via ::name->event producesread-model-schemassrc/cjbarre/grain_todo_list/service/todo_list_service/schemas.clj - Todo schemas (tasks, projects, weekly review)src/cjbarre/grain_todo_list/service/user_service/schemas.clj - User/auth schemasGive your AI agents something more useful than a prompt. Velocity through clarity.
Visual quality gate — screenshot each primary screen, critique it against the baseline rubric, and refine the components until it passes. Use before declaring a build done.
Implement command handlers that validate state, emit events, and return signals using the Grain framework
Create scheduled background jobs that run on cron schedules
Implement query handlers that read from event-sourced read models and render hiccup
Build read models by reducing events into queryable state with defreadmodel