diff --git a/.claude/agents/feature-implementer.md b/.claude/agents/feature-implementer.md index d808866..b6bfe9c 100644 --- a/.claude/agents/feature-implementer.md +++ b/.claude/agents/feature-implementer.md @@ -93,7 +93,7 @@ When implementing a feature: - `useFormElementVisibility` - Visibility condition evaluation - `useSectionSpawning` - Template section spawning -- `useClonableElements` - Element cloning logic +- `useFormElementDuplication` - Element cloning logic - `useFormElementValueClearing` - Clear hidden element values - `useTableCrossReferences` - Table column/row references - `useApplicationFormValidator` - Form validation diff --git a/.claude/skills/coolify/SKILL.md b/.claude/skills/coolify/SKILL.md new file mode 100644 index 0000000..cb6f056 --- /dev/null +++ b/.claude/skills/coolify/SKILL.md @@ -0,0 +1,62 @@ +--- +name: coolify +description: Use when user asks you to use this skill to debug Coolify issues or to investigate something related to Coolify. +--- + +# Coolify + +## Overview + +Opens Playwright MCP, lets the user log in to Coolify, and then takes a snapshot for further investigation. + +## Coolify Instance + +- **Primary URL:** `https://coolify.gremiumhub.de/` + +## Process + +1. Open the browser +2. If you know the URL related to the current request, navigate to that URL or ask the user to do so. Otherwise, assume + the user needs to log in first and navigate to log in if the user does not provide a URL + (`mcp__playwright__browser_navigate → https://coolify.gremiumhub.de/login`) +3. (If not logged in) Stop and wait for user to log in. +4. (When logged in) Navigate to the page that might be related to the current request if the user has not done so. Ask + for the content of the page if this might be easier for you to understand the issue. + +## Additional Notes + +- If you need to do something in the terminal, write down all commands first that you want to execute and ask the user + to execute them. Do not execute any command directly. +- Write down in a summary what you have changed in the Coolify instance. +- If you encounter an error while opening the browser (e.g., "browserType.launchPersistentContext: Failed to launch the + browser process"), ask the user to restart the browser and stop until the user confirms that the browser is restarted + or that you can try to open the browser again. +- Always rely on the docker-compose files and configured environment variables in the Coolify instance to understand how + the instance is set up and how it works. Do not assume anything that is not explicitly stated in the docker-compose + files or environment variables. If you are not sure about something, ask the user to check the docker-compose files + and environment variables instead of making assumptions. +- Ignore the local deployment files. Only rely on settings and configurations that are actually used in the running instance. If you are not sure which files are relevant, ask the user to check which files are actually used in the running instance instead of making assumptions. + +## Efficient Data Extraction + +**Env vars — use Developer view:** Click it via JS (button refs are unreliable in Livewire apps), then read the textarea: +```js +// Click Developer view +Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim().includes('Developer view'))?.click() +// Read all vars at once +document.querySelector('textarea')?.value +``` + +**Compose file — Coolify uses Monaco editor:** +```js +window.monaco?.editor?.getModels()?.[0]?.getValue() +``` + +Prefer JS extraction over screenshots/scrolling for any text data. + +## Key Behavioral Notes + +- **`$SERVICE_*` magic variables are only substituted in the compose file**, not in manually-added panel env vars. Panel vars with `$SERVICE_URL_*` values are passed as literal strings to containers — this causes `NOT_SET` errors in Nuxt OAuth when `NUXT_OAUTH_KEYCLOAK_SERVER_URL=$SERVICE_URL_KEYCLOAK` is set via the panel instead of the compose. +- **Panel vars are driven by the compose file.** Coolify syncs env vars from the compose into the panel — they are not independent. You cannot delete a variable from the panel without first removing it from the compose file. To fix a value, edit the compose file; the panel updates automatically. +- **`$SERVICE_URL_*`** includes `https://`; **`$SERVICE_FQDN_*`** is hostname only (no protocol). Mixing them breaks JWT issuer validation. +- The "Hardcoded variables are not shown here" warning refers to vars with fully hardcoded literal values in the compose. Vars referencing `$SERVICE_*` or `${VAR}` do appear in the panel. diff --git a/.claude/skills/seed-yaml-sync/SKILL.md b/.claude/skills/seed-yaml-sync/SKILL.md index 780a55c..c9668c7 100644 --- a/.claude/skills/seed-yaml-sync/SKILL.md +++ b/.claude/skills/seed-yaml-sync/SKILL.md @@ -158,6 +158,13 @@ When adding a new section file: 2. Add the `!include` directive to the corresponding `_main.yaml` 3. Maintain logical section ordering +### Rule 9: Change process must start with template, then sync demo + +Any change request that affects form structure, visibility conditions, or section spawn triggers must follow this process: +1. **Modify the template**: Make all necessary changes to the template files first, ensuring structural integrity and logical consistency +2. **Sync the demo form**: After the template is updated, modify the demo form to mirror the structural changes and add contextually appropriate test data +3. **Verify both**: Ensure that the template remains the source of truth and that the demo form accurately reflects the template's structure and visibility logic + ## Checklist for Template Changes When you modify files in the **template/ directory**, verify each item: @@ -179,4 +186,4 @@ When you modify files in the **demo/ directory**, verify: - [ ] **Value consistency**: New values are consistent with the SAP S/4HANA "Einfuehrung" context - [ ] **Table data alignment**: Table JSON arrays all have the same length within a single table element - [ ] **Cross-reference integrity**: Table values that reference other tables use valid IDs from those tables -- [ ] **_main.yaml update**: If you added/removed a section file, update `demo/_main.yaml` \ No newline at end of file +- [ ] **_main.yaml update**: If you added/removed a section file, update `demo/_main.yaml` diff --git a/CLAUDE.md b/CLAUDE.md index c224a38..68508bb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -120,8 +120,9 @@ See subproject CLAUDE.md files for component-specific key files. a. Modify `api/legalconsenthub.yml` OpenAPI spec first b. Regenerate frontend client: `cd legalconsenthub && pnpm run api:generate` c. Regenerate backend stubs: `cd legalconsenthub-backend && ./gradlew generate_legalconsenthub_server` - d. Implement backend controller methods (they implement generated interfaces) - e. Use generated client in frontend (never write manual API calls) + d. **Update backend entity class AND mapper class** for every new DTO field — fields missing from the entity silently return `null` from the API. If the new field requires database storage, note that a SQL migration is needed (the user handles migrations). + e. Implement backend controller methods (they implement generated interfaces) + f. Use generated client in frontend (never write manual API calls) 2. **Organization context** - Always consider `organizationId` for multi-tenancy. Forms with empty/null organizationId are "global" forms visible to all organizations 3. **Form structure is 3-level** - Section → SubSection → Element 4. **Roles managed in Keycloak** - Not in application database diff --git a/legalconsenthub-backend/CLAUDE.md b/legalconsenthub-backend/CLAUDE.md index f2bfb3b..6f0ffc4 100644 --- a/legalconsenthub-backend/CLAUDE.md +++ b/legalconsenthub-backend/CLAUDE.md @@ -97,6 +97,8 @@ formElementSections: 1. **Never add SQL migrations** - They will be handled by the user 2. **Use mapper classes** - All DTO ↔ Entity conversions must happen in dedicated mapper classes (never in services/controllers) + - **CRITICAL: Entity + Mapper must be updated together** — When a new field is added to an OpenAPI DTO, you MUST update BOTH the entity class AND the mapper. A field present in the DTO but absent from the entity will silently return `null` from the API with no compile error. New entity fields that are persisted require a SQL migration (the user handles this). + - For JSON-typed fields (e.g. `GroupCondition`), use `@JdbcTypeCode(SqlTypes.JSON)` + `@Column(columnDefinition = "jsonb")`, same as `FormElement.visibilityConditions`. 3. **PDF Export Validation** - After changes to form elements, visibility, or spawning: - Test both HTML and PDF export for real form instances - Verify all element types render correctly diff --git a/legalconsenthub/CLAUDE.md b/legalconsenthub/CLAUDE.md index 27cb351..96a407a 100644 --- a/legalconsenthub/CLAUDE.md +++ b/legalconsenthub/CLAUDE.md @@ -18,7 +18,7 @@ | ----------------------------- | ---------------------------------------- | | `useFormElementVisibility` | Evaluate visibility conditions | | `useSectionSpawning` | Process spawn triggers, clone templates | -| `useClonableElements` | Clone elements with reference generation | +| `useFormElementDuplication` | Clone elements with reference generation | | `useFormElementValueClearing` | Clear values when elements become hidden | | `useTableCrossReferences` | Resolve table column/row references | | `useApplicationFormValidator` | Form validation rules |