Skip to content

Commit cb14d1b

Browse files
committed
Merge branch 'release/1.9.0'
2 parents 7fa5821 + e1ef964 commit cb14d1b

142 files changed

Lines changed: 6965 additions & 3601 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/agents/create-migration.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
name: create-migration
3+
description: Generate and validate a Doctrine migration after entity changes
4+
model: sonnet
5+
---
6+
7+
After entity changes, generate and validate a Doctrine migration:
8+
9+
1. Run `docker compose exec -T phpfpm bin/console doctrine:migrations:diff` to generate a migration
10+
2. Read the generated migration file and verify the SQL looks correct
11+
3. Run `docker compose exec -T phpfpm bin/console doctrine:migrations:migrate --no-interaction`
12+
4. Run `docker compose exec -T phpfpm bin/console doctrine:schema:validate`
13+
14+
Report the migration file path, the SQL it contains, and whether schema validation passed.
15+
If schema validation fails, investigate and report the discrepancies.

.claude/agents/pr-readiness.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: pr-readiness
3+
description: Run all CI-equivalent checks locally before creating a PR
4+
model: haiku
5+
---
6+
7+
Run the following checks in sequence inside Docker and report results for each.
8+
Stop early if a critical check fails.
9+
10+
## Checks
11+
12+
1. **Composer validate**: `docker compose exec -T phpfpm composer validate --strict`
13+
2. **Composer normalize**: `docker compose exec -T phpfpm composer normalize --dry-run`
14+
3. **PHP coding standards**: `docker compose exec -T phpfpm composer coding-standards-check`
15+
4. **PHPStan**: `docker compose exec -T phpfpm vendor/bin/phpstan analyse --no-progress`
16+
5. **PHPUnit tests**: `docker compose exec -T phpfpm composer tests`
17+
6. **Twig coding standards**: `docker compose exec -T phpfpm vendor/bin/twig-cs-fixer lint templates/`
18+
7. **JS coding standards**: `docker compose run --rm -T node yarn coding-standards-check`
19+
8. **API spec up to date**: Run `docker compose exec -T phpfpm composer update-api-spec`, then check `git diff --exit-code public/api-spec-v1.*`
20+
9. **CHANGELOG updated**: Verify CHANGELOG.md has changes compared to the base branch (`git diff develop -- CHANGELOG.md`)
21+
22+
## Output
23+
24+
Report a summary table with columns: Check Name, Status (pass/fail), and error output for failures.

.claude/settings.json

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
{
2+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
3+
"env": {
4+
"COMPOSE_USER": "deploy"
5+
},
6+
"permissions": {
7+
"allow": [
8+
"Bash(cat:*)",
9+
"Bash(diff:*)",
10+
"Bash(echo:*)",
11+
"Bash(find:*)",
12+
"Bash(gh:*)",
13+
"Bash(git:*)",
14+
"Bash(grep:*)",
15+
"Bash(head:*)",
16+
"Bash(ls:*)",
17+
"Bash(pwd)",
18+
"Bash(tail:*)",
19+
"Bash(task:*)",
20+
"Bash(tree:*)",
21+
"Bash(wc:*)",
22+
"Bash(which:*)",
23+
"Bash(docker compose exec:*)",
24+
"Bash(docker compose run:*)",
25+
"Bash(docker compose up:*)",
26+
"Bash(docker compose ps:*)",
27+
"Bash(docker compose logs:*)",
28+
"Bash(docker compose top:*)",
29+
"Bash(docker compose config:*)",
30+
"Bash(docker compose pull:*)",
31+
"Bash(docker compose images:*)",
32+
"Bash(docker network:*)"
33+
],
34+
"deny": [
35+
"Bash(rm -rf:*)",
36+
"Bash(gh issue delete:*)",
37+
"Bash(gh release delete:*)",
38+
"Bash(gh repo delete:*)",
39+
"Bash(gh label delete:*)",
40+
"Read(./.env.local)",
41+
"Read(./.env.local.*)",
42+
"Read(./config/secrets/*)"
43+
],
44+
"ask": [
45+
"Bash(docker compose down:*)",
46+
"Bash(docker compose stop:*)",
47+
"Bash(docker compose rm:*)",
48+
"Bash(docker compose restart:*)",
49+
"Bash(gh issue create:*)",
50+
"Bash(gh issue close:*)",
51+
"Bash(gh issue edit:*)",
52+
"Bash(gh issue comment:*)",
53+
"Bash(gh pr create:*)",
54+
"Bash(gh pr close:*)",
55+
"Bash(gh pr merge:*)",
56+
"Bash(gh pr edit:*)",
57+
"Bash(gh pr comment:*)",
58+
"Bash(gh pr review:*)",
59+
"Bash(gh release create:*)",
60+
"Bash(gh release edit:*)",
61+
"Bash(gh repo create:*)",
62+
"Bash(gh label create:*)",
63+
"Bash(gh label edit:*)",
64+
"Bash(git push:*)",
65+
"Bash(git branch -d:*)",
66+
"Bash(git branch -D:*)",
67+
"Bash(git tag -d:*)",
68+
"Bash(git tag -a:*)",
69+
"Bash(git tag :*)",
70+
"Bash(git reset:*)",
71+
"Bash(git rebase:*)",
72+
"Bash(git merge:*)",
73+
"Bash(git stash drop:*)",
74+
"Bash(git clean:*)",
75+
"Bash(git checkout -- :*)",
76+
"Bash(git restore:*)",
77+
"Bash(git commit:*)"
78+
]
79+
},
80+
"hooks": {
81+
"SessionStart": [
82+
{
83+
"matcher": "startup",
84+
"hooks": [
85+
{
86+
"type": "command",
87+
"command": "docker compose up --detach --quiet-pull 2>/dev/null || true",
88+
"timeout": 60,
89+
"statusMessage": "Starting Docker services..."
90+
}
91+
]
92+
}
93+
],
94+
"PreToolUse": [
95+
{
96+
"matcher": "Edit|Write",
97+
"hooks": [
98+
{
99+
"type": "command",
100+
"command": "case \"$CLAUDE_FILE_PATH\" in */composer.lock|*/yarn.lock|*/.env.local|*/.env.local.*) echo 'BLOCKED: Do not edit lock files or .env.local directly' >&2; exit 1 ;; esac"
101+
}
102+
]
103+
}
104+
],
105+
"PostToolUse": [
106+
{
107+
"matcher": "Write|Edit",
108+
"hooks": [
109+
{
110+
"type": "command",
111+
"command": "case \"$CLAUDE_FILE_PATH\" in *.php) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/php-cs-fixer fix --quiet \"$REL_PATH\" 2>/dev/null || true ;; esac",
112+
"timeout": 30
113+
},
114+
{
115+
"type": "command",
116+
"command": "case \"$CLAUDE_FILE_PATH\" in *.php) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/phpstan analyse --no-progress --error-format=raw \"$REL_PATH\" 2>/dev/null || true ;; esac",
117+
"timeout": 30
118+
},
119+
{
120+
"type": "command",
121+
"command": "case \"$CLAUDE_FILE_PATH\" in *.twig) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/twig-cs-fixer lint --fix \"$REL_PATH\" 2>/dev/null || true ;; esac",
122+
"timeout": 15
123+
},
124+
{
125+
"type": "command",
126+
"command": "case \"$CLAUDE_FILE_PATH\" in */composer.json) docker compose exec -T phpfpm composer normalize --quiet 2>/dev/null || true ;; esac",
127+
"timeout": 30
128+
},
129+
{
130+
"type": "command",
131+
"command": "case \"$CLAUDE_FILE_PATH\" in *.js|*.css|*.scss|*.yaml|*.yml|*.md) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose run --rm -T node npx prettier --write \"$REL_PATH\" 2>/dev/null || true ;; esac",
132+
"timeout": 15
133+
}
134+
]
135+
}
136+
],
137+
"Stop": [
138+
{
139+
"hooks": [
140+
{
141+
"type": "command",
142+
"command": "docker compose exec -T phpfpm bin/console lint:container 2>/dev/null || true",
143+
"timeout": 30,
144+
"statusMessage": "Validating Symfony DI container..."
145+
}
146+
]
147+
}
148+
]
149+
},
150+
"enabledPlugins": {
151+
"php-lsp@claude-plugins-official": true,
152+
"code-simplifier@claude-plugins-official": true,
153+
"context7@claude-plugins-official": true,
154+
"code-review@claude-plugins-official": true,
155+
"security-guidance@claude-plugins-official": true,
156+
"playwright@claude-plugins-official": true,
157+
"feature-dev@claude-plugins-official": true,
158+
"itkdev-skills@itkdev-marketplace": true
159+
}
160+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
name: update-api-spec
3+
description: Regenerate and stage API spec files after API resource changes
4+
user-invocable: true
5+
---
6+
7+
When API resources or operations change, regenerate the OpenAPI spec files:
8+
9+
1. Run `docker compose exec -T phpfpm composer update-api-spec`
10+
2. Check `git diff public/api-spec-v1.*` for changes
11+
3. If changed, stage the spec files with `git add public/api-spec-v1.yaml public/api-spec-v1.json`
12+
4. Report what changed in the API spec

.docker/data/.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Ignore everything in this directory
22
*
3-
# Except this file
3+
# Except
44
!.gitignore
5-
!Readme.md
5+
!README.md

.docker/nginx.conf

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ http {
1717
include /etc/nginx/mime.types;
1818
default_type application/octet-stream;
1919

20-
set_real_ip_from 172.16.0.0/16;
21-
real_ip_recursive on;
22-
real_ip_header X-Forwarded-For;
20+
# Note: set_real_ip_from is set in the server block
2321

2422
log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" '
2523
'$status $body_bytes_sent "$http_referer" '

.docker/templates/default.conf.template

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@ server {
66

77
client_max_body_size ${NGINX_MAX_BODY_SIZE};
88

9-
# This also needs to be set in the single server tag and not only in http.
109
set_real_ip_from 172.16.0.0/16;
10+
set_real_ip_from 192.168.39.0/24;
1111
real_ip_recursive on;
1212
real_ip_header X-Forwarded-For;
1313

14+
location = /cron-metrics {
15+
# Proxy to supercronic metrics
16+
proxy_pass http://${NGINX_CRON_METRICS}/metrics;
17+
proxy_set_header Host $host;
18+
proxy_set_header X-Real-IP $remote_addr;
19+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
20+
proxy_set_header X-Forwarded-Proto $scheme;
21+
}
22+
1423
location / {
1524
# try to serve file directly, fallback to index.php
1625
try_files $uri /index.php$is_args$args;

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
COMPOSE_PROJECT_NAME=itksites
2-
#COMPOSE_DOMAIN=itksites.local.itkdev.dk
3-
COMPOSE_DOMAIN=sites.itkdev.dk
2+
COMPOSE_DOMAIN=itksites.local.itkdev.dk
3+
ITKDEV_TEMPLATE=symfony-8
44

55
# In all environments, the following files are loaded if they exist,
66
# the latter taking precedence over the former:

0 commit comments

Comments
 (0)