Upload feature (e): wire inline upload (registratie beroep) + documenten step (herregistratie)

- Fold UploadState into both wizard machines; route via { tag: 'Upload', msg }
- Gate step validation on requiredCategoriesSatisfied; include deliveryRefs in submit
- Shared createUploadController (effectful glue: categories, transport, focus-poll, File map)
- rejectReason pure format validator + specs; bump registratie storage key to v2

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-06-30 08:38:37 +02:00
co-authored by Claude Opus 4.8
parent 9521739ac1
commit bfd957a6d4
13 changed files with 341 additions and 66 deletions
@@ -9,6 +9,7 @@ import {
requiredCategoriesSatisfied,
deliveryRefs,
inFlight,
rejectReason,
} from './upload.machine';
const cat = (over: Partial<DocumentCategory> = {}): DocumentCategory => ({
@@ -217,6 +218,21 @@ describe('deliveryRefs', () => {
});
});
describe('rejectReason', () => {
it('rejects a disallowed type', () => {
expect(rejectReason(cat({ acceptedTypes: ['application/pdf'] }), { type: 'image/png', sizeMb: 1 })).toBe('type');
});
it('rejects an oversized file', () => {
expect(rejectReason(cat({ maxSizeMb: 10 }), { type: 'application/pdf', sizeMb: 11 })).toBe('size');
});
it('accepts a valid file', () => {
expect(rejectReason(cat({ acceptedTypes: ['application/pdf'], maxSizeMb: 10 }), { type: 'application/pdf', sizeMb: 1 })).toBeNull();
});
it('allows any type when the category lists none', () => {
expect(rejectReason(cat({ acceptedTypes: [], maxSizeMb: 10 }), { type: 'image/png', sizeMb: 1 })).toBeNull();
});
});
describe('inFlight', () => {
it('returns only queued/uploading uploads', () => {
let s = select(stateWith([cat({ multiple: true })]), 'diploma', 'u1');