@@ -43,7 +43,7 @@ export function registerModelsCommand(program: Command): void {
4343 // models get
4444 const get = models
4545 . command ( "get <id>" )
46- . description ( "Get a data model's full schema including property definitions and constraints" )
46+ . description ( "Get a data model's full schema including property definitions, validation rules, and unique constraints" )
4747 . action (
4848 withErrorHandler ( async ( id : unknown , _opts : unknown , cmd : Command ) => {
4949 const client = createClient ( cmd ) ;
@@ -81,7 +81,11 @@ export function registerModelsCommand(program: Command): void {
8181 ' "propertyDetails": {\n' +
8282 ' "temperature": {"ngsiType": "Property", "valueType": "Number", "example": 25}\n' +
8383 " }\n" +
84- " }" ,
84+ " }\n\n" +
85+ "Optional uniqueConstraints (composite unique, enforced server-side):\n" +
86+ ' "uniqueConstraints": [{"name": "no-double-booking", "fields": ["room", "date", "startTime"]}]\n' +
87+ " Fields must be declared in propertyDetails with a scalar valueType.\n" +
88+ " Duplicate entities are rejected with 409 AlreadyExists (constraint name in the message)." ,
8589 )
8690 . action (
8791 withErrorHandler ( async ( json : unknown , _opts : unknown , cmd : Command ) => {
@@ -107,6 +111,10 @@ export function registerModelsCommand(program: Command): void {
107111 description : "Create from stdin pipe" ,
108112 command : "cat model.json | geonic models create" ,
109113 } ,
114+ {
115+ description : "Create with a composite unique constraint (no double booking)" ,
116+ command : `geonic models create '{"type":"RoomReservation","domain":"building","description":"Room reservation","propertyDetails":{"room":{"ngsiType":"Property","valueType":"string","example":"R1"},"date":{"ngsiType":"Property","valueType":"string","example":"2026-07-15"},"startTime":{"ngsiType":"Property","valueType":"string","example":"10:00"}},"uniqueConstraints":[{"name":"no-double-booking","fields":["room","date","startTime"]}]}'` ,
117+ } ,
110118 ] ) ;
111119
112120 // models update
@@ -116,7 +124,9 @@ export function registerModelsCommand(program: Command): void {
116124 . description (
117125 "Update a model\n\n" +
118126 "JSON payload: only specified fields are updated.\n" +
119- ' e.g. {"description": "Updated model"}' ,
127+ ' e.g. {"description": "Updated model"}\n\n' +
128+ "uniqueConstraints replaces the whole constraint list (send [] to remove all).\n" +
129+ "Adding a constraint fails with 400 if existing entities already violate it." ,
120130 )
121131 . action (
122132 withErrorHandler (
@@ -148,6 +158,14 @@ export function registerModelsCommand(program: Command): void {
148158 description : "Update from stdin pipe" ,
149159 command : "cat model.json | geonic models update <model-id>" ,
150160 } ,
161+ {
162+ description : "Replace unique constraints" ,
163+ command : `geonic models update RoomReservation '{"uniqueConstraints":[{"name":"no-double-booking","fields":["room","date","startTime"]}]}'` ,
164+ } ,
165+ {
166+ description : "Remove all unique constraints" ,
167+ command : `geonic models update RoomReservation '{"uniqueConstraints":[]}'` ,
168+ } ,
151169 ] ) ;
152170
153171 // models delete
0 commit comments