refactor(forms): move packages/form-schema → apps/app/src/composables/forms

Inlines the form-schema source folder (no package.json, alias-only)
into apps/app/src/composables/forms. Drops the @form-schema alias
from apps/app/vite.config.ts (replaced by @/composables/forms via
the existing @ alias). apps/portal vite + vitest configs keep
@form-schema as a temporary alias pointing at the new location so
portal tests/build keep working until apps/portal is removed at the
end of this PR. Two pure-logic form-schema tests moved alongside.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 18:50:52 +02:00
parent 966ded3e44
commit 79954aace6
13 changed files with 9 additions and 29 deletions

View File

@@ -1,12 +1,12 @@
import { describe, expect, it } from 'vitest'
import { formatFieldValue } from '@form-schema/composables/formatFieldValue'
import { FormFieldType } from '@form-schema/types/formBuilder'
import { formatFieldValue } from '@/composables/forms/composables/formatFieldValue'
import { FormFieldType } from '@/composables/forms/types/formBuilder'
import type {
AvailableTag,
PublicFormField,
PublicFormSectionOption,
PublicFormTimeSlot,
} from '@form-schema/types/formBuilder'
} from '@/composables/forms/types/formBuilder'
function field(partial: Partial<PublicFormField> = {}): PublicFormField {
return {

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'
import { evaluateConditionalLogic } from '@form-schema/composables/useConditionalLogic'
import type { ConditionalLogic } from '@form-schema/types/formBuilder'
import { evaluateConditionalLogic } from '@/composables/forms/composables/useConditionalLogic'
import type { ConditionalLogic } from '@/composables/forms/types/formBuilder'
describe('evaluateConditionalLogic', () => {
it('returns true when logic is null or undefined', () => {

View File

@@ -111,9 +111,6 @@ export default defineConfig({
import.meta.url,
),
),
'@form-schema': fileURLToPath(
new URL('../../packages/form-schema/src', import.meta.url),
),
},
},
server: {

View File

@@ -84,7 +84,8 @@ export default defineConfig({
'@images': fileURLToPath(new URL('./src/assets/images/', import.meta.url)),
'@styles': fileURLToPath(new URL('./src/assets/styles/', import.meta.url)),
'@configured-variables': fileURLToPath(new URL('./src/assets/styles/variables/_template.scss', import.meta.url)),
'@form-schema': fileURLToPath(new URL('../../packages/form-schema/src', import.meta.url)),
// Temporary alias during WS-3 PR-B1 transition; portal is deleted at PR end.
'@form-schema': fileURLToPath(new URL('../app/src/composables/forms', import.meta.url)),
},
},
server: {

View File

@@ -23,7 +23,8 @@ export default defineConfig({
'@images': fileURLToPath(new URL('./src/assets/images/', import.meta.url)),
'@styles': fileURLToPath(new URL('./src/assets/styles/', import.meta.url)),
'@validators': fileURLToPath(new URL('./src/@core/utils/validators', import.meta.url)),
'@form-schema': fileURLToPath(new URL('../../packages/form-schema/src', import.meta.url)),
// Temporary alias during WS-3 PR-B1 transition; portal is deleted at PR end.
'@form-schema': fileURLToPath(new URL('../app/src/composables/forms', import.meta.url)),
},
},
test: {

View File

@@ -1,19 +0,0 @@
# @form-schema
Shared schema contract and schema-driven behaviors for Crewli form rendering. Consumed by apps/portal (public submission) and apps/app (organizer builder + submissions review).
## What lives here
- `types/` — TypeScript types and enum constants mirroring backend `FormBuilder` enums and `PublicForm(Schema|Submission)Resource`
- `utils/formValidation.ts` — validation rule builders driven by `FormFieldValidationRules`
- `composables/useConditionalLogic.ts` — evaluate `conditional_logic.show_when` against field values
- `composables/useFormSteps.ts` — step navigation logic for multi-step forms
- `composables/formatFieldValue.ts` — render a stored submission value as a human-readable string
## What does NOT live here
Vue components. Each app renders its own UI. Portal has full-fidelity submit components; app has builder-preview and submissions-review components. Sharing renderers would couple the two apps' visual styles, which we explicitly want to avoid.
## Contract stability
This is an alias-only shared directory inside the monorepo — no npm package, no semver. Breaking changes (new field type, new validation key, new conditional operator) require updating both apps in the same PR. TypeScript will flag missing cases in dispatchers.