So uh, I'm not familiar with designing a schema to store form responses with relational database. But here's what I've collected by far:
Zod ⇔ JSON Schema:
P.S. The library's README suggests using eval(). Use new Function() instead.
Form Rendering
- Auto Form. Convert the stored JSON schema back to zod.
Database design
e.g.:
model Form {
id String @id @default(dbgenerated("gen_random_uuid()"))
creationTimestamp DateTime @default(now())
user User @relation(fields: [userId], references: [id])
userId String
club Club @relation(fields: [clubId], references: [id])
clubId Int
formSchema String // A JSON Schema converted from Zod
FormResponse FormResponse[]
}
model FormResponse {
id String @id @default(dbgenerated("gen_random_uuid()"))
creationTimestamp DateTime @default(now())
user User @relation(fields: [userId], references: [id])
userId String
form Form @relation(fields: [formId], references: [id])
formId String
response Json // A JSON object that conforms to the schema as designed in the form
}
It's best to validate the response data being fed into the database every INSERT or UPDATE.
Resources:
- pg_jsonschema
- Enable postgres extensions in Prisma
- We need a trigger at postgresql every UPDATE or INSERT. Check constraints won't work because they don't support subqueries. eg:
CREATE OR REPLACE FUNCTION validate_formresponse_schema()
RETURNS TRIGGER AS $$
BEGIN
-- Validate that the meta field matches the schema
PERFORM jsonb_matches_schema(
NEW.form.formSchema,
NEW.response
);
-- If validation passes, proceed with the insert/update
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER validate_formresponse_schema_trigger
BEFORE INSERT OR UPDATE ON FormResponse
FOR EACH ROW
EXECUTE FUNCTION alidate_formresponse_schema();
So uh, I'm not familiar with designing a schema to store form responses with relational database. But here's what I've collected by far:
Zod ⇔ JSON Schema:
P.S. The library's README suggests using
eval(). Usenew Function()instead.Form Rendering
Database design
e.g.:
It's best to validate the response data being fed into the database every
INSERTorUPDATE.Resources: