Coverage for postrfp/ref/handlers/designers.py: 100%
43 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
1"""
2HTTP endpoints for managing ContentSchema objects
3"""
5from typing import Optional
7from sqlalchemy.orm import Session
9from postrfp.shared.pager import Pager
10from postrfp.authorisation import perms
11from postrfp.shared.decorators import http
12from postrfp.model.humans import User
13from postrfp.model.ref import ContentSpec
14from postrfp.shared.serial.refmodels import ContentSchema, ListResponse
17@http
18def get_specs(
19 session: Session,
20 user: User,
21 q_name: Optional[str] = None,
22 pager: Optional[Pager] = None,
23) -> ListResponse:
24 """
25 List all content schemas accessible to the user's organization
27 Content schemas define the structure, validation rules, and field definitions
28 for content items. Schemas are organization-owned and control how structured
29 content is created and validated within the system.
31 **Query Parameters:**
32 - `q_name`: Filter schemas by name (case-insensitive partial match)
33 - Standard pagination parameters supported
35 **Returns:** Paginated list of schema definitions accessible to the user
37 **Access Control:**
38 Schemas are filtered to show only:
39 - Schemas owned by the user's organization
40 - Schemas shared with the user's organization (if sharing is implemented)
42 **Schema Information Includes:**
43 - Schema identification (ID, name, description)
44 - JSON Schema definition with validation rules
45 - Creation and modification timestamps
46 - Owning organization details
47 - Current workflow status
49 **Use Cases:**
50 - Browse available content templates
51 - Find schemas for specific content types
52 - Understand validation requirements before content creation
53 - Manage organization's content structure standards
55 **Examples:**
56 - Get all schemas: no query parameters
57 - Search by name: `?q_name=financial report`
58 """
59 if pager is None:
60 pager = Pager(page=1, page_size=20)
62 # Start query with schemas owned by user's org or shared with them
63 query = (
64 session.query(ContentSpec)
65 .filter((ContentSpec.org_id == user.org_id))
66 .order_by(ContentSpec.name)
67 )
69 if q_name:
70 query = query.filter(ContentSpec.name.ilike(f"%{q_name}%"))
72 total_records = query.count()
73 records = query.slice(pager.startfrom, pager.goto).all()
75 return ListResponse(
76 items=[ContentSchema.model_validate(schema) for schema in records],
77 pagination=pager.as_pagination(total_records, len(records)),
78 )
81@http
82def get_spec(session: Session, user: User, spec_id: int) -> ContentSchema:
83 """
84 Get a single content schema by ID
86 Retrieves the complete schema definition including all field specifications,
87 validation rules, metadata, and documentation. Essential for understanding
88 content structure requirements and implementing content creation interfaces.
90 **Path Parameters:**
91 - `spec_id`: Unique identifier of the content schema
93 **Returns:** Complete schema definition including:
94 - Schema identification and metadata
95 - Full JSON Schema specification with all validation rules
96 - Field definitions and constraints
97 - Required vs optional field specifications
98 - Data types and format requirements
99 - Custom validation patterns
100 - Creation and modification history
102 **JSON Schema Features:**
103 The returned schema follows JSON Schema Draft 7+ specifications and may include:
104 - Field type definitions (string, number, object, array, etc.)
105 - Validation constraints (min/max length, patterns, enums)
106 - Nested object structures
107 - Array item specifications
108 - Conditional field requirements
109 - Custom format validators
111 **Use Cases:**
112 - Generate content creation forms dynamically
113 - Validate content before submission
114 - Understand content structure for API integration
115 - Document content requirements for users
117 **Raises:**
118 - `NoResultFound`: If the schema ID does not exist
119 - `AuthorizationFailure`: If the user lacks access to this schema
120 """
121 content_spec = session.get_one(ContentSpec, spec_id)
123 return ContentSchema.model_validate(content_spec)
126@http
127def post_spec(session: Session, user: User, spec_doc: ContentSchema) -> ContentSchema:
128 """
129 Create a new content schema
131 Creates a new JSON Schema definition that will control the structure and
132 validation of content items. The schema becomes available for content creation
133 within the user's organization and can define complex data structures.
135 **Request Body:** Schema document including:
136 - `name`: Descriptive name for the schema (required)
137 - `description`: Detailed explanation of the schema purpose
138 - `spec_doc`: Complete JSON Schema definition (required)
140 **Returns:** Created schema with assigned ID and metadata
142 **JSON Schema Requirements:**
143 The `spec_doc` must be a valid JSON Schema (Draft 7+ recommended) including:
144 - Root `type` definition (typically "object")
145 - `properties` defining all available fields
146 - `required` array listing mandatory fields
147 - Field-level validation constraints
148 - Proper data type specifications
150 **Schema Validation:**
151 The system validates that:
152 - The JSON Schema syntax is correct
153 - Required fields are properly defined
154 - Type definitions are valid
155 - Constraints are logically consistent
157 **Ownership:**
158 - Schema is owned by the user's organization
159 - Only the owning organization can modify the schema
160 - Content created with this schema will reference the organization
162 **Best Practices:**
163 - Use descriptive field names and documentation
164 - Define appropriate validation constraints
165 - Consider backward compatibility for schema updates
166 - Include examples in the schema description
168 **@permissions REF_SPEC_SAVE**
170 **Examples:**
171 ```json
172 {
173 "name": "Financial Report Schema",
174 "description": "Quarterly financial reporting template",
175 "spec_doc": {
176 "type": "object",
177 "properties": {
178 "report_period": {"type": "string", "format": "date"},
179 "revenue": {"type": "number", "minimum": 0},
180 "expenses": {"type": "number", "minimum": 0}
181 },
182 "required": ["report_period", "revenue", "expenses"]
183 }
184 }
185 ```
186 """
187 user.check_permission(perms.REF_SPEC_SAVE)
189 # Create new schema
190 new_content_spec = ContentSpec(
191 name=spec_doc.name,
192 description=spec_doc.description,
193 spec_doc=spec_doc.spec_doc,
194 auth_policy=spec_doc.auth_policy,
195 org_id=user.org_id, # Always use the current user's org ID for ownership
196 )
197 session.add(new_content_spec)
199 session.flush()
200 return ContentSchema.model_validate(new_content_spec)
203@http
204def put_spec(
205 session: Session, user: User, spec_id: int, spec_doc: ContentSchema
206) -> ContentSchema:
207 """
208 Update an existing content schema
210 Modifies an existing schema definition with new validation rules and structure.
211 This is a potentially breaking change that may affect existing content items
212 that use this schema, so it should be used carefully.
214 **Path Parameters:**
215 - `spec_id`: ID of the schema to update
217 **Request Body:** Complete schema document (all fields will be updated)
218 - `name`: Updated descriptive name for the schema
219 - `description`: Updated explanation of schema purpose
220 - `spec_doc`: Complete updated JSON Schema definition
222 **Returns:** Updated schema with new timestamps and metadata
224 **Breaking Change Considerations:**
225 - Existing content may no longer validate against the updated schema
226 - New required fields will cause validation failures for existing content
227 - Changed field types or constraints may break existing content
228 - Removed fields will be ignored in existing content but may cause confusion
230 **Schema Evolution Best Practices:**
231 - Add new optional fields rather than required ones
232 - Avoid removing existing fields that contain data
233 - Use schema versioning for major structural changes
234 - Consider deprecation warnings before removing fields
235 - Test schema changes against existing content
237 **Validation Impact:**
238 - Content validation occurs during content creation and updates
239 - Existing content is not automatically re-validated
240 - Invalid content may become accessible but not editable
241 - New content must pass validation with the updated schema
243 **@permissions REF_SPEC_SAVE**
245 **Raises:**
246 - `NoResultFound`: If the schema ID does not exist
247 - `AuthorizationFailure`: If the user's organization doesn't own this schema
248 - `ValidationError`: If the updated JSON Schema is invalid
250 **Migration Strategy:**
251 For major schema changes, consider:
252 1. Creating a new schema version
253 2. Migrating content to the new schema gradually
254 3. Deprecating the old schema after migration
255 4. Providing clear migration documentation
256 """
257 user.check_permission(perms.REF_SPEC_SAVE)
259 content_spec = session.get_one(ContentSpec, spec_id)
261 # Update schema fields
262 content_spec.name = spec_doc.name
263 content_spec.description = spec_doc.description
264 content_spec.spec_doc = spec_doc.spec_doc
265 content_spec.auth_policy = spec_doc.auth_policy
267 return ContentSchema.model_validate(content_spec)
270@http
271def delete_spec(session: Session, user: User, spec_id: int) -> None:
272 """
273 Delete a content schema
275 Permanently removes a schema definition from the system. This is a destructive
276 operation that will affect all content items using this schema and should be
277 used with extreme caution.
279 **Path Parameters:**
280 - `spec_id`: ID of the schema to delete
282 **Returns:** None (204 No Content status)
284 **Critical Impact:**
285 - **All content using this schema will become invalid**
286 - Content items will no longer pass validation
287 - Existing content becomes uneditable (validation failures)
288 - Content creation with this schema becomes impossible
289 - API responses may include validation warnings
291 **What Gets Deleted:**
292 - The schema definition itself
293 - All validation rules and field specifications
294 - Schema metadata and documentation
295 - Workflow state information for the schema
297 **Content Impact:**
298 Content items using this schema will:
299 - Remain accessible for viewing (existing data preserved)
300 - Fail validation checks during editing attempts
301 - Display warnings about missing schema
302 - Require schema reassignment or recreation for continued use
304 **Permission Requirements:**
305 - User's organization must own the schema
306 - Only the schema owner can delete it
307 - Cannot be deleted if it would violate system constraints
309 **Recommended Alternatives:**
310 Instead of deletion, consider:
311 - Deprecating the schema (mark as inactive)
312 - Creating a migration path to a new schema
313 - Archiving content using the schema first
314 - Updating the schema to a minimal valid state
316 **@permissions REF_SPEC_SAVE**
318 **Raises:**
319 - `NoResultFound`: If the schema ID does not exist
320 - `AuthorizationFailure`: If the user's organization doesn't own this schema
321 - `IntegrityError`: If content still depends on this schema (depending on DB constraints)
323 **⚠️ Warning:** This action cannot be undone. Ensure all content using this schema
324 has been migrated or archived before proceeding with deletion.
325 """
326 user.check_permission(perms.REF_SPEC_SAVE)
328 schema = session.get_one(ContentSpec, spec_id)
330 session.delete(schema)