Fix H3, H6, H11, H13, M11, M18 — quick wins from expert review

H3: mizanFetch retries 2x on server errors (5xx) and network
failures. 200ms/400ms backoff. Mutations NOT retried (not idempotent).

H6: refreshContext now uses GET /ctx/<name>/ instead of POST /call/.
Context reads go to the context endpoint, not the mutation endpoint.

H11: Python cache key derivation normalizes True→"true",
False→"false", None→"null" for cross-language HMAC consistency
with JavaScript's String() behavior.

H13: Forms isValid now checks that all required fields have been
touched, not just that touched fields have no errors.

M11: execute_function return type updated to include HttpResponseBase
for view-path functions.

M18: registerContext cleanup uses ?. instead of ! to prevent crash
if Map was cleared (already fixed in H2 commit but documenting).

373 Django + 33 React tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 12:30:10 -04:00
parent cdd15b3810
commit 9c837cf285
5 changed files with 47 additions and 8 deletions

View File

@@ -367,11 +367,12 @@ export function MizanProvider({
[contextStore]
)
// Refresh a specific context
// Refresh a specific context via GET /ctx/<name>/
const refreshContext = useCallback(
async (name: string): Promise<void> => {
try {
const data = await call(name, {})
const response = await httpClient.request('GET', `${baseUrl}/ctx/${name}/`)
const data = await response.json()
setContextStore(prev => {
const next = { ...prev, [name]: data }
// Notify listeners

View File

@@ -811,8 +811,16 @@ export function useMizanFormCore<TData extends Record<string, unknown>>(
}, [errors, touchedFields])
const isValid = useMemo(() => {
return errors !== null && !hasErrors
}, [errors, hasErrors])
if (errors === null || hasErrors) return false
// Also check that all required fields have been touched
if (schema) {
for (const fieldName of schema.fieldOrder) {
const field = schema.fields[fieldName]
if (field.required && !touchedFields.has(fieldName)) return false
}
}
return true
}, [errors, hasErrors, schema, touchedFields])
return {
data,