feat(defects): add shared arktype defect input schema
Shared validation source for the DefectForm and /api/defects route (Task 5): trimmed non-empty sectionId/verbatim and a uuid projectId.
This commit is contained in:
19
shared/schemas/defect.ts
Normal file
19
shared/schemas/defect.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { type } from 'arktype'
|
||||
|
||||
/**
|
||||
* The user-supplied fields when filing a defect. `reporterEmail` and the
|
||||
* timestamp are resolved server-side (getReporter / DB default), so they are
|
||||
* not part of this input. This is the single source of validation truth shared
|
||||
* by the DefectForm and the /api/defects route (wired in Task 5); import it via
|
||||
* the `#shared` alias from either client or server.
|
||||
*/
|
||||
export const defectInput = type({
|
||||
// section_id comes from the clicked board section — a non-empty slug.
|
||||
sectionId: type('string.trim').to('string >= 1'),
|
||||
// projectId references projects.id, a uuid.
|
||||
projectId: 'string.uuid',
|
||||
// The reporter's words — required, trimmed.
|
||||
verbatim: type('string.trim').to('string >= 1'),
|
||||
})
|
||||
|
||||
export type DefectInput = typeof defectInput.infer
|
||||
29
tests/defect-schema.spec.ts
Normal file
29
tests/defect-schema.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { type } from 'arktype'
|
||||
import { defectInput } from '../shared/schemas/defect'
|
||||
|
||||
const valid = {
|
||||
sectionId: 'a4-flow',
|
||||
projectId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
verbatim: 'The thing broke',
|
||||
}
|
||||
|
||||
describe('defectInput schema', () => {
|
||||
it('accepts a valid defect and trims verbatim', () => {
|
||||
const out = defectInput({ ...valid, verbatim: ' hi ' })
|
||||
expect(out instanceof type.errors).toBe(false)
|
||||
expect((out as typeof valid).verbatim).toBe('hi')
|
||||
})
|
||||
|
||||
it('rejects empty verbatim', () => {
|
||||
expect(defectInput({ ...valid, verbatim: '' }) instanceof type.errors).toBe(true)
|
||||
})
|
||||
|
||||
it('rejects whitespace-only verbatim', () => {
|
||||
expect(defectInput({ ...valid, verbatim: ' ' }) instanceof type.errors).toBe(true)
|
||||
})
|
||||
|
||||
it('rejects a non-uuid projectId', () => {
|
||||
expect(defectInput({ ...valid, projectId: 'not-a-uuid' }) instanceof type.errors).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user