Compare commits

..

6 Commits
main ... dev

118 changed files with 11782 additions and 521 deletions

View File

@ -1,3 +1,3 @@
# catterpillar
# caterpillar
Web Application to get medicines information from barcode using open data

2
TODO Normal file
View File

@ -0,0 +1,2 @@
- Create data bulk SQL import
- Create all mecine doctrine entities

76
api/.editorconfig Normal file
View File

@ -0,0 +1,76 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 4
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{js,html,ts,tsx}]
indent_style = space
indent_size = 2
[*.json]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[*.php]
indent_style = space
indent_size = 4
[*.sh]
indent_style = tab
indent_size = 4
[*.xml{,.dist}]
indent_style = space
indent_size = 4
[*.{yaml,yml}]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false
[helm/api-platform/**.yaml]
indent_style = space
indent_size = 2
[.github/workflows/*.yml]
indent_style = space
indent_size = 2
[.gitmodules]
indent_style = tab
indent_size = 4
[.php_cs{,.dist}]
indent_style = space
indent_size = 4
[.travis.yml]
indent_style = space
indent_size = 2
[composer.json]
indent_style = space
indent_size = 4
[docker-compose{,.*}.{yaml,yml}]
indent_style = space
indent_size = 2
[Dockerfile]
indent_style = tab
indent_size = 4

19
api/.gitattributes vendored Normal file
View File

@ -0,0 +1,19 @@
* text=auto eol=lf
*.conf text eol=lf
*.html text eol=lf
*.ini text eol=lf
*.js text eol=lf
*.json text eol=lf
*.md text eol=lf
*.php text eol=lf
*.sh text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
bin/console text eol=lf
composer.lock text eol=lf merge=ours
*.ico binary
*.png binary
update-deps.sh export-ignore

13
api/.gitignore vendored
View File

@ -1,10 +1,3 @@
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###
/.env
/helm/api-platform/charts/*
!/helm/api-platform/charts/.gitignore

19
api/LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2015-present Kévin Dunglas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

21
api/README.md Normal file
View File

@ -0,0 +1,21 @@
# API
## Setup
### Requirements
- docker
- docker-compose
### Installation
```bash
docker-compose build
docker-compose up -d
```
For a one-liner
```bash
docker-compose up -d --build
```

30
api/api/.dockerignore Normal file
View File

@ -0,0 +1,30 @@
**/*.log
**/*.md
**/*.php~
**/*.dist.php
**/*.dist
**/*.cache
**/._*
**/.dockerignore
**/.DS_Store
**/.git/
**/.gitattributes
**/.gitignore
**/.gitmodules
**/docker-compose.*.yaml
**/docker-compose.*.yml
**/docker-compose.yaml
**/docker-compose.yml
**/Dockerfile
**/Thumbs.db
.github/
docs/
public/bundles/
tests/
var/
vendor/
.editorconfig
.env.*.local
.env.local
.env.local.php
.env.test

View File

@ -14,9 +14,13 @@
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
# API Platform distribution
TRUSTED_PROXIES=127.0.0.1
TRUSTED_HOSTS=^localhost$
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=2880857c2abf85444c6bd5a924771ce2
APP_SECRET=!ChangeMe!
###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ###
@ -25,9 +29,19 @@ APP_SECRET=2880857c2abf85444c6bd5a924771ce2
#
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
DATABASE_URL="postgresql://caterpillar:!ChangeMe!@127.0.0.1:5432/catterpillar?serverVersion=14&charset=utf8"
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8"
###< doctrine/doctrine-bundle ###
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###
###> symfony/mercure-bundle ###
# See https://symfony.com/doc/current/mercure.html#configuration
# The URL of the Mercure hub, used by the app to publish updates (can be a local URL)
MERCURE_URL=http://caddy/.well-known/mercure
# The public URL of the Mercure hub, used by the browser to connect
MERCURE_PUBLIC_URL=https://localhost/.well-known/mercure
# The secret used to sign the JWTs
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
###< symfony/mercure-bundle ###

9
api/api/.env.test Normal file
View File

@ -0,0 +1,9 @@
# define your env variables for the test env here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
# API Platform distribution
TRUSTED_HOSTS=^example\.com|localhost$

21
api/api/.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
/docker/db/data
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###
###> friendsofphp/php-cs-fixer ###
/.php-cs-fixer.php
/.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
###> symfony/phpunit-bridge ###
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###

View File

@ -0,0 +1,13 @@
<?php
$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
->exclude('var')
;
return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,
])
->setFinder($finder)
;

139
api/api/Dockerfile Normal file
View File

@ -0,0 +1,139 @@
#syntax=docker/dockerfile:1.4
# Adapted from https://github.com/dunglas/symfony-docker
# Prod image
FROM php:8.1-fpm-alpine AS app_php
ENV APP_ENV=prod
WORKDIR /srv/app
# persistent / runtime deps
RUN apk add --no-cache \
acl \
fcgi \
file \
gettext \
git \
;
RUN set -eux; \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
icu-data-full \
icu-dev \
libzip-dev \
zlib-dev \
; \
\
docker-php-ext-configure zip; \
docker-php-ext-install -j$(nproc) \
intl \
zip \
; \
pecl install \
apcu \
; \
pecl clear-cache; \
docker-php-ext-enable \
apcu \
opcache \
; \
\
runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)"; \
apk add --no-cache --virtual .app-phpexts-rundeps $runDeps; \
\
apk del .build-deps
###> recipes ###
###> doctrine/doctrine-bundle ###
RUN apk add --no-cache --virtual .pgsql-deps postgresql-dev; \
docker-php-ext-install -j$(nproc) pdo_pgsql; \
apk add --no-cache --virtual .pgsql-rundeps so:libpq.so.5; \
apk del .pgsql-deps
###< doctrine/doctrine-bundle ###
###< recipes ###
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY --link docker/php/conf.d/app.ini $PHP_INI_DIR/conf.d/
COPY --link docker/php/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/
COPY --link docker/php/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf
RUN mkdir -p /var/run/php
COPY --link docker/php/docker-healthcheck.sh /usr/local/bin/docker-healthcheck
RUN chmod +x /usr/local/bin/docker-healthcheck
HEALTHCHECK --interval=10s --timeout=3s --retries=3 CMD ["docker-healthcheck"]
COPY --link docker/php/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
RUN chmod +x /usr/local/bin/docker-entrypoint
ENTRYPOINT ["docker-entrypoint"]
CMD ["php-fpm"]
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV PATH="${PATH}:/root/.composer/vendor/bin"
COPY --from=composer:2 --link /usr/bin/composer /usr/bin/composer
# prevent the reinstallation of vendors at every changes in the source code
COPY composer.* symfony.* ./
RUN set -eux; \
composer install --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress; \
composer clear-cache
# copy sources
COPY --link . .
RUN rm -Rf docker/
RUN set -eux; \
mkdir -p var/cache var/log; \
composer dump-autoload --classmap-authoritative --no-dev; \
composer dump-env prod; \
composer run-script --no-dev post-install-cmd; \
chmod +x bin/console; sync
# Dev image
FROM app_php AS app_php_dev
ENV APP_ENV=dev XDEBUG_MODE=off
VOLUME /srv/app/var/
RUN rm $PHP_INI_DIR/conf.d/app.prod.ini; \
mv "$PHP_INI_DIR/php.ini" "$PHP_INI_DIR/php.ini-production"; \
mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
COPY --link docker/php/conf.d/app.dev.ini $PHP_INI_DIR/conf.d/
RUN set -eux; \
apk add --no-cache --virtual .build-deps $PHPIZE_DEPS; \
pecl install xdebug; \
docker-php-ext-enable xdebug; \
apk del .build-deps
RUN rm -f .env.local.php
# Build Caddy with the Mercure and Vulcain modules
FROM caddy:2-builder-alpine AS app_caddy_builder
RUN xcaddy build \
--with github.com/dunglas/mercure \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain \
--with github.com/dunglas/vulcain/caddy
# Caddy image
FROM caddy:2-alpine AS app_caddy
WORKDIR /srv/app
COPY --from=app_caddy_builder --link /usr/bin/caddy /usr/bin/caddy
COPY --from=app_php --link /srv/app/public public/
COPY --link docker/caddy/Caddyfile /etc/caddy/Caddyfile

5
api/api/README.md Normal file
View File

@ -0,0 +1,5 @@
# API
The API will be here.
Refer to the [Getting Started Guide](https://api-platform.com/docs/distribution) for more information.

19
api/api/bin/phpunit Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env php
<?php
if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
PHPUnit\TextUI\Command::main();
} else {
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
exit(1);
}
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
}

View File

@ -1,48 +1,58 @@
{
"type": "project",
"license": "proprietary",
"minimum-stability": "stable",
"prefer-stable": true,
"license": "MIT",
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0",
"doctrine/annotations": "^1.0",
"api-platform/core": "dev-main",
"composer/package-versions-deprecated": "1.11.99.5",
"doctrine/annotations": "^1.13",
"doctrine/doctrine-bundle": "^2.7",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.13",
"doctrine/orm": "^2.12",
"guzzlehttp/guzzle": "^7.4",
"nelmio/cors-bundle": "^2.2",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.8",
"symfony/asset": "6.1.*",
"symfony/console": "6.1.*",
"symfony/dotenv": "6.1.*",
"symfony/expression-language": "6.1.*",
"symfony/flex": "^2",
"symfony/flex": "^2.2",
"symfony/framework-bundle": "6.1.*",
"symfony/mercure-bundle": "^0.3.5",
"symfony/monolog-bundle": "^3.8",
"symfony/property-access": "6.1.*",
"symfony/property-info": "6.1.*",
"symfony/proxy-manager-bridge": "6.1.*",
"symfony/runtime": "6.1.*",
"symfony/security-bundle": "6.1.*",
"symfony/serializer": "6.1.*",
"symfony/twig-bundle": "6.1.*",
"symfony/validator": "6.1.*",
"symfony/yaml": "6.1.*",
"webonyx/graphql-php": "^14.11"
"symfony/yaml": "6.1.*"
},
"require-dev": {
"api-platform/schema-generator": "^4.0",
"symfony/browser-kit": "6.1.*",
"symfony/css-selector": "6.1.*",
"symfony/debug-bundle": "6.1.*",
"symfony/maker-bundle": "^1.44",
"symfony/phpunit-bridge": "6.1.*",
"symfony/stopwatch": "6.1.*",
"symfony/var-dumper": "6.1.*",
"symfony/web-profiler-bundle": "6.1.*"
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"symfony/flex": true,
"symfony/runtime": true
},
"optimize-autoloader": true,
"preferred-install": {
"*": "dist"
},
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"composer/package-versions-deprecated": true,
"symfony/flex": true,
"symfony/runtime": true
}
},
"autoload": {
"psr-4": {
@ -55,13 +65,14 @@
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php73": "*",
"symfony/polyfill-php74": "*",
"symfony/polyfill-php80": "*",
"symfony/polyfill-php81": "*"
"symfony/polyfill-php74": "*",
"symfony/polyfill-php73": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php71": "*"
},
"scripts": {
"auto-scripts": {
@ -81,7 +92,8 @@
"extra": {
"symfony": {
"allow-contrib": false,
"require": "6.1.*"
"require": "6.1.*",
"docker": false
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
<?php
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (!class_exists(Dotenv::class)) {
throw new LogicException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
}
// Load cached env vars if the .env.local.php file exists
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
if (is_array($env = @include dirname(__DIR__).'/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) {
(new Dotenv())->usePutenv(false)->populate($env);
} else {
// load all the .env files
(new Dotenv())->usePutenv(false)->loadEnv(dirname(__DIR__).'/.env');
}
$_SERVER += $_ENV;
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';

View File

@ -2,10 +2,15 @@
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
];

View File

@ -1,6 +1,8 @@
api_platform:
title: Caterpillar API
version: 0.0.0
title: Hello API Platform
version: 1.0.0
# Mercure integration, remove if unwanted
mercure: ~
# Good cache defaults for REST APIs
defaults:
stateless: true

View File

@ -0,0 +1,5 @@
when@dev:
debug:
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
# See the "server:dump" command to start a new server.
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

View File

@ -0,0 +1,4 @@
debug:
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
# See the "server:dump" command to start a new server.
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"

View File

@ -0,0 +1,19 @@
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]

View File

@ -0,0 +1,3 @@
framework:
router:
strict_requirements: true

View File

@ -0,0 +1,6 @@
web_profiler:
toolbar: true
intercept_redirects: false
framework:
profiler: { only_exceptions: false }

View File

@ -0,0 +1,29 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
http_method_override: false
trusted_proxies: '%env(TRUSTED_PROXIES)%'
trusted_hosts: '%env(TRUSTED_HOSTS)%'
# See https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#headers
trusted_headers: [ 'x-forwarded-for', 'x-forwarded-proto' ]
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
#session:
# handler_id: null
# cookie_secure: auto
# cookie_samesite: lax
# storage_factory_id: session.storage.factory.native
#esi: true
#fragments: true
php_errors:
log: true
when@test:
framework:
test: true
#session:
# storage_factory_id: session.storage.factory.mock_file

View File

@ -0,0 +1,8 @@
mercure:
hubs:
default:
url: '%env(MERCURE_URL)%'
public_url: '%env(MERCURE_PUBLIC_URL)%'
jwt:
secret: '%env(MERCURE_JWT_SECRET)%'
publish: '*'

View File

@ -0,0 +1,61 @@
monolog:
channels:
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
when@dev:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
when@test:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
when@prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: php://stderr
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: php://stderr

View File

@ -3,7 +3,7 @@ nelmio_cors:
origin_regex: true
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
allow_headers: ['Content-Type', 'Authorization', 'Preload', 'Fields']
expose_headers: ['Link']
max_age: 3600
paths:

View File

@ -0,0 +1,8 @@
# As of Symfony 5.1, deprecations are logged in the dedicated "deprecation" channel when it exists
#monolog:
# channels: [deprecation]
# handlers:
# deprecation:
# type: stream
# channels: [deprecation]
# path: php://stderr

View File

@ -0,0 +1,17 @@
doctrine:
orm:
auto_generate_proxy_classes: false
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system

View File

@ -0,0 +1,17 @@
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: php://stderr
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]

View File

@ -0,0 +1,4 @@
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'

View File

@ -0,0 +1,12 @@
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug

View File

@ -0,0 +1,3 @@
framework:
router:
strict_requirements: true

View File

@ -0,0 +1,3 @@
framework:
validation:
not_compromised_password: false

View File

@ -0,0 +1,6 @@
web_profiler:
toolbar: false
intercept_redirects: false
framework:
profiler: { collect: false }

View File

@ -0,0 +1,17 @@
when@dev:
web_profiler:
toolbar: true
intercept_redirects: false
framework:
profiler:
only_exceptions: false
collect_serializer_data: true
when@test:
web_profiler:
toolbar: false
intercept_redirects: false
framework:
profiler: { collect: false }

View File

@ -0,0 +1,7 @@
controllers:
resource: ../../src/Controller/
type: annotation
kernel:
resource: ../../src/Kernel.php
type: annotation

View File

@ -1,4 +1,3 @@
api_platform:
resource: .
type: api_platform
prefix: /api

View File

@ -0,0 +1,7 @@
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: /_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: /_profiler

View File

@ -0,0 +1,8 @@
when@dev:
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: /_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: /_profiler

View File

@ -0,0 +1,57 @@
{
# Debug
{$DEBUG}
# HTTP/3 support
servers {
protocol {
experimental_http3
}
}
}
{$SERVER_NAME}
log
# Matches requests for HTML documents, for static files and for Next.js files,
# except for known API paths and paths with extensions handled by API Platform
@pwa expression `(
header({'Accept': '*text/html*'})
&& !path(
'/docs*', '/graphql*', '/bundles*', '/contexts*', '/_profiler*', '/_wdt*',
'*.json*', '*.html', '*.csv', '*.yml', '*.yaml', '*.xml'
)
)
|| path('/favicon.ico', '/manifest.json', '/robots.txt', '/_next*', '/sitemap*')`
route {
root * /srv/app/public
mercure {
# Transport to use (default to Bolt)
transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
# Publisher JWT key
publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
# Subscriber JWT key
subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
# Allow anonymous subscribers (double-check that it's what you want)
anonymous
# Enable the subscription API (double-check that it's what you want)
subscriptions
# Extra directives
{$MERCURE_EXTRA_DIRECTIVES}
}
vulcain
# Add links to the API docs and to the Mercure Hub if not set explicitly (e.g. the PWA)
header ?Link `</docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation", </.well-known/mercure>; rel="mercure"`
# Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics
header ?Permissions-Policy "browsing-topics=()"
# Comment the following line if you don't want Next.js to catch requests for HTML documents.
# In this case, they will be handled by the PHP app.
reverse_proxy @pwa http://{$PWA_UPSTREAM}
php_fastcgi unix//var/run/php/php-fpm.sock
encode zstd gzip
file_server
}

View File

@ -0,0 +1,5 @@
; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host
; See https://github.com/docker/for-linux/issues/264
; The `client_host` below may optionally be replaced with `discover_client_host=yes`
; Add `start_with_request=yes` to start debug session on each request
xdebug.client_host = 'host.docker.internal'

View File

@ -0,0 +1,13 @@
expose_php = 0
date.timezone = UTC
apc.enable_cli = 1
session.use_strict_mode = 1
zend.detect_unicode = 0
; https://symfony.com/doc/current/performance.html
realpath_cache_size = 4096K
realpath_cache_ttl = 600
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
opcache.enable_file_override = 1

View File

@ -0,0 +1,2 @@
opcache.preload_user = www-data
opcache.preload = /srv/app/config/preload.php

View File

@ -0,0 +1,45 @@
#!/bin/sh
set -e
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- php-fpm "$@"
fi
if [ "$1" = 'php-fpm' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then
setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var
setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var
if [ "$APP_ENV" != 'prod' ]; then
composer install --prefer-dist --no-progress --no-interaction
fi
if grep -q DATABASE_URL= .env; then
echo "Waiting for database to be ready..."
ATTEMPTS_LEFT_TO_REACH_DATABASE=60
until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do
if [ $? -eq 255 ]; then
# If the Doctrine command exits with 255, an unrecoverable error occurred
ATTEMPTS_LEFT_TO_REACH_DATABASE=0
break
fi
sleep 1
ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1))
echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left."
done
if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then
echo "The database is not up or not reachable:"
echo "$DATABASE_ERROR"
exit 1
else
echo "The database is now ready and reachable"
fi
if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then
php bin/console doctrine:migrations:migrate --no-interaction
fi
fi
fi
exec docker-php-entrypoint "$@"

View File

@ -0,0 +1,8 @@
#!/bin/sh
set -e
if env -i REQUEST_METHOD=GET SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping cgi-fcgi -bind -connect /var/run/php/php-fpm.sock; then
exit 0
fi
exit 1

View File

@ -0,0 +1,8 @@
[global]
daemonize = no
process_control_timeout = 20
[www]
listen = /var/run/php/php-fpm.sock
listen.mode = 0666
ping.path = /ping

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20210930074739 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SEQUENCE greeting_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE greeting (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('DROP SEQUENCE greeting_id_seq CASCADE');
$this->addSql('DROP TABLE greeting');
}
}

42
api/api/phpunit.xml.dist Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
convertDeprecationsToExceptions="false"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<!-- Run `composer require symfony/panther` before enabling this extension -->
<!--
<extensions>
<extension class="Symfony\Component\Panther\ServerExtension" />
</extensions>
-->
</phpunit>

View File

@ -1,7 +1,5 @@
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Link;
use Doctrine\Common\Collections\ArrayCollection;
@ -23,10 +21,6 @@ class MedicineAdministrationWay
#[ORM\Column]
private ?string $CIS = null;
/** The medicine that is admnistrate this way. */
#[ORM\ManyToOne(inversedBy: 'ways')]
public ?MedicineSpeciality $medicine = null;
/**
* The drug administration way
*/

View File

@ -1,7 +1,5 @@
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Link;
use Doctrine\ORM\Mapping as ORM;
@ -26,10 +24,6 @@ class MedicineHolder
#[ORM\Column]
private string $name = '';
/** The medicament this entity holds */
#[ORM\ManyToOne(inversedBy: 'holders')]
private ?MedicineSpeciality $medicine;
public function getId(): ?int
{
return $this->id;
@ -44,24 +38,4 @@ class MedicineHolder
{
return $this->name;
}
public function setCIS(string $CIS): self
{
$this->CIS = $CIS;
return $this;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function __toString(): string
{
return $this->name;
}
}

View File

@ -1,9 +1,6 @@
<?php
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\Link;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
@ -18,52 +15,48 @@ use Doctrine\ORM\Mapping as ORM;
*/
#[ORM\Entity]
#[ApiResource]
// #[ApiResource(
// uriTemplate: '/medicine/'
// )]
// #[ApiResource(
// uriTemplate: '/medicine/{CIS}',
// uriVariables: [
// 'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
// ]
// )]
// #[ApiResource(
// uriTemplate: '/medicine/{CIS}/holder',
// uriVariables: [
// 'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
// ]
// )]
// #[ApiResource(
// uriTemplate: '/medicine/{CIS}/holder/{id}',
// uriVariables: [
// 'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
// 'id' => new Link(fromClass: MedicineHolder::class, fromProperty: 'id'),
// ]
// )]
// #[ApiResource(
// uriTemplate: '/medicine/{CIS}/way',
// uriVariables: [
// 'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
// ]
// )]
// #[ApiResource(
// uriTemplate: '/medicine/{CIS}/way/{id}',
// uriVariables: [
// 'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
// 'id' => new Link(fromClass: MedicineAdministrationWay::class, fromProperty: 'id'),
// ]
// )]
#[ApiResource(
uriTemplate: '/medicine/'
)]
#[ApiResource(
uriTemplate: '/medicine/{CIS}',
uriVariables: [
'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
]
)]
#[ApiResource(
uriTemplate: '/medicine/{CIS}/holder',
uriVariables: [
'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
]
)]
#[ApiResource(
uriTemplate: '/medicine/{CIS}/holder/{id}',
uriVariables: [
'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
'id' => new Link(fromClass: MedicineHolder::class, fromProperty: 'id'),
]
)]
#[ApiResource(
uriTemplate: '/medicine/{CIS}/way',
uriVariables: [
'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
]
)]
#[ApiResource(
uriTemplate: '/medicine/{CIS}/way/{id}',
uriVariables: [
'CIS' => new Link(fromClass: MedicineSpeciality::class, fromProperty: 'CIS'),
'id' => new Link(fromClass: MedicineAdministrationWay::class, fromProperty: 'id'),
]
)]
class MedicineSpeciality
{
#[ORM\Id, ORM\Column,ORM\GeneratedValue]
private ?int $id = null;
/**
* This CIS (Code Identifiant de Spécialité) id is the unique identifier of the medicine.
*/
#[ORM\Column]
#[ApiProperty(identifier: true)]
#[ORM\Id, ORM\Column]
private ?int $CIS = null;
/**
@ -132,7 +125,7 @@ class MedicineSpeciality
*
* @var MedicineHolder[] Holders of the medicine market authorization (AMM)
*/
#[ORM\OneToMany(mappedBy: 'medicine', targetEntity: MedicineHolder::class, cascade: ['persist', 'remove'])]
#[ORM\OneToMany]
public iterable $holders;
/**
@ -143,11 +136,10 @@ class MedicineSpeciality
#[ORM\Column]
private ?string $enforced_surveillance = null;
public function __construct()
{
$this->holders = new ArrayCollection();
$this->ways = new ArrayCollection();
}
// public function __construct()
// {
// }
public function getCIS(): ?int
{

553
api/api/symfony.lock Normal file
View File

@ -0,0 +1,553 @@
{
"api-platform/core": {
"version": "3.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.0",
"ref": "0330386d716d3eecc52ee5ac66976e733eb8f961"
},
"files": [
"config/routes/api_platform.yaml",
"src/ApiResource/.gitignore"
]
},
"api-platform/schema-generator": {
"version": "v4.0.0"
},
"composer/package-versions-deprecated": {
"version": "1.11.99.4"
},
"composer/pcre": {
"version": "1.0.0"
},
"composer/semver": {
"version": "3.2.7"
},
"composer/xdebug-handler": {
"version": "2.0.4"
},
"doctrine/annotations": {
"version": "1.13",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.10",
"ref": "64d8583af5ea57b7afa4aba4b159907f3a148b05"
}
},
"doctrine/cache": {
"version": "2.1.1"
},
"doctrine/collections": {
"version": "1.6.8"
},
"doctrine/common": {
"version": "3.2.1"
},
"doctrine/dbal": {
"version": "3.2.1"
},
"doctrine/deprecations": {
"version": "v0.5.3"
},
"doctrine/doctrine-bundle": {
"version": "2.7",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.4",
"ref": "da713d006953b90d1c085c1be480ecdd6c4a95e0"
},
"files": [
"config/packages/doctrine.yaml",
"src/Entity/.gitignore",
"src/Repository/.gitignore"
]
},
"doctrine/doctrine-cache-bundle": {
"version": "1.3.5"
},
"doctrine/doctrine-migrations-bundle": {
"version": "3.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.1",
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
},
"files": [
"config/packages/doctrine_migrations.yaml",
"migrations/.gitignore"
]
},
"doctrine/event-manager": {
"version": "1.1.1"
},
"doctrine/inflector": {
"version": "2.0.4"
},
"doctrine/instantiator": {
"version": "1.4.0"
},
"doctrine/lexer": {
"version": "1.2.1"
},
"doctrine/migrations": {
"version": "3.3.2"
},
"doctrine/orm": {
"version": "2.10.4"
},
"doctrine/persistence": {
"version": "2.3.0"
},
"doctrine/reflection": {
"version": "1.2.1"
},
"doctrine/sql-formatter": {
"version": "1.1.2"
},
"easyrdf/easyrdf": {
"version": "1.1.1"
},
"fig/link-util": {
"version": "1.2.0"
},
"friendsofphp/php-cs-fixer": {
"version": "3.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "3.0",
"ref": "be2103eb4a20942e28a6dd87736669b757132435"
},
"files": [
".php-cs-fixer.dist.php"
]
},
"friendsofphp/proxy-manager-lts": {
"version": "v1.0.5"
},
"guzzlehttp/guzzle": {
"version": "7.4.1"
},
"guzzlehttp/promises": {
"version": "1.5.1"
},
"guzzlehttp/psr7": {
"version": "2.1.0"
},
"laminas/laminas-code": {
"version": "4.5.1"
},
"laminas/laminas-eventmanager": {
"version": "3.3.1"
},
"laminas/laminas-zendframework-bridge": {
"version": "1.2.0"
},
"lcobucci/clock": {
"version": "2.1.0"
},
"lcobucci/jwt": {
"version": "4.1.5"
},
"league/html-to-markdown": {
"version": "5.0.2"
},
"monolog/monolog": {
"version": "2.3.5"
},
"nelmio/cors-bundle": {
"version": "1.5",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "1.5",
"ref": "6bea22e6c564fba3a1391615cada1437d0bde39c"
},
"files": [
"config/packages/nelmio_cors.yaml"
]
},
"nette/php-generator": {
"version": "v3.6.5"
},
"nette/utils": {
"version": "v3.2.6"
},
"nikic/php-parser": {
"version": "v4.13.2"
},
"ocramius/package-versions": {
"version": "1.9.0"
},
"php": {
"version": "7.4"
},
"php-cs-fixer/diff": {
"version": "v2.0.2"
},
"phpdocumentor/reflection-common": {
"version": "2.2.0"
},
"phpdocumentor/reflection-docblock": {
"version": "5.3.0"
},
"phpdocumentor/type-resolver": {
"version": "1.6.0"
},
"psr/cache": {
"version": "3.0.0"
},
"psr/container": {
"version": "2.0.2"
},
"psr/event-dispatcher": {
"version": "1.0.0"
},
"psr/http-client": {
"version": "1.0.1"
},
"psr/http-factory": {
"version": "1.0.1"
},
"psr/http-message": {
"version": "1.0.1"
},
"psr/link": {
"version": "2.0.1"
},
"psr/log": {
"version": "3.0.0"
},
"ralouphie/getallheaders": {
"version": "3.0.3"
},
"symfony/asset": {
"version": "v6.0.1"
},
"symfony/browser-kit": {
"version": "v6.0.1"
},
"symfony/cache": {
"version": "v6.0.2"
},
"symfony/cache-contracts": {
"version": "v3.0.0"
},
"symfony/config": {
"version": "v6.0.2"
},
"symfony/console": {
"version": "5.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "5.3",
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
},
"files": [
"bin/console"
]
},
"symfony/css-selector": {
"version": "v6.0.2"
},
"symfony/debug-bundle": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.3",
"ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b"
},
"files": [
"config/packages/debug.yaml"
]
},
"symfony/dependency-injection": {
"version": "v6.0.2"
},
"symfony/deprecation-contracts": {
"version": "v3.0.0"
},
"symfony/doctrine-bridge": {
"version": "v6.0.2"
},
"symfony/dom-crawler": {
"version": "v6.0.2"
},
"symfony/dotenv": {
"version": "v6.0.2"
},
"symfony/error-handler": {
"version": "v6.0.2"
},
"symfony/event-dispatcher": {
"version": "v6.0.2"
},
"symfony/event-dispatcher-contracts": {
"version": "v3.0.0"
},
"symfony/expression-language": {
"version": "v6.0.1"
},
"symfony/filesystem": {
"version": "v6.0.0"
},
"symfony/finder": {
"version": "v6.0.2"
},
"symfony/flex": {
"version": "2.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.0",
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
},
"files": [
".env"
]
},
"symfony/framework-bundle": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.4",
"ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb"
},
"files": [
"config/packages/cache.yaml",
"config/packages/framework.yaml",
"config/preload.php",
"config/routes/framework.yaml",
"config/services.yaml",
"public/index.php",
"src/Controller/.gitignore",
"src/Kernel.php"
]
},
"symfony/http-client": {
"version": "v6.0.2"
},
"symfony/http-client-contracts": {
"version": "v3.0.0"
},
"symfony/http-foundation": {
"version": "v6.0.2"
},
"symfony/http-kernel": {
"version": "v6.0.2"
},
"symfony/maker-bundle": {
"version": "1.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "1.0",
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
}
},
"symfony/mercure": {
"version": "v0.6.1"
},
"symfony/mercure-bundle": {
"version": "0.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "0.3",
"ref": "e0a854b5439186e04b28fb8887b42c54f24a0d32"
},
"files": [
"config/packages/mercure.yaml"
]
},
"symfony/monolog-bridge": {
"version": "v6.0.1"
},
"symfony/monolog-bundle": {
"version": "3.8",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "3.7",
"ref": "213676c4ec929f046dfde5ea8e97625b81bc0578"
},
"files": [
"config/packages/monolog.yaml"
]
},
"symfony/options-resolver": {
"version": "v6.0.0"
},
"symfony/password-hasher": {
"version": "v6.0.2"
},
"symfony/phpunit-bridge": {
"version": "5.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "5.3",
"ref": "97cb3dc7b0f39c7cfc4b7553504c9d7b7795de96"
},
"files": [
".env.test",
"bin/phpunit",
"phpunit.xml.dist",
"tests/bootstrap.php"
]
},
"symfony/polyfill-intl-grapheme": {
"version": "v1.24.0"
},
"symfony/polyfill-intl-normalizer": {
"version": "v1.24.0"
},
"symfony/polyfill-mbstring": {
"version": "v1.24.0"
},
"symfony/polyfill-php70": {
"version": "v1.20.0"
},
"symfony/polyfill-php81": {
"version": "v1.24.0"
},
"symfony/process": {
"version": "v6.0.2"
},
"symfony/property-access": {
"version": "v6.0.2"
},
"symfony/property-info": {
"version": "v6.0.2"
},
"symfony/routing": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.1",
"ref": "a44010c0d06989bd4f154aa07d2542d47caf5b83"
},
"files": [
"config/packages/routing.yaml",
"config/routes.yaml"
]
},
"symfony/runtime": {
"version": "v6.0.0"
},
"symfony/security-bundle": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.0",
"ref": "8a5b112826f7d3d5b07027f93786ae11a1c7de48"
},
"files": [
"config/packages/security.yaml"
]
},
"symfony/security-core": {
"version": "v6.0.2"
},
"symfony/security-csrf": {
"version": "v6.0.1"
},
"symfony/security-guard": {
"version": "v5.3.7"
},
"symfony/security-http": {
"version": "v6.0.2"
},
"symfony/serializer": {
"version": "v6.0.2"
},
"symfony/service-contracts": {
"version": "v3.0.0"
},
"symfony/stopwatch": {
"version": "v6.0.0"
},
"symfony/string": {
"version": "v6.0.2"
},
"symfony/translation-contracts": {
"version": "v3.0.0"
},
"symfony/twig-bridge": {
"version": "v6.0.2"
},
"symfony/twig-bundle": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.4",
"ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
},
"files": [
"config/packages/twig.yaml",
"templates/base.html.twig"
]
},
"symfony/validator": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "5.3",
"ref": "c32cfd98f714894c4f128bb99aa2530c1227603c"
},
"files": [
"config/packages/validator.yaml"
]
},
"symfony/var-dumper": {
"version": "v6.0.2"
},
"symfony/var-exporter": {
"version": "v6.0.0"
},
"symfony/web-link": {
"version": "v6.0.1"
},
"symfony/web-profiler-bundle": {
"version": "6.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.1",
"ref": "e42b3f0177df239add25373083a564e5ead4e13a"
},
"files": [
"config/packages/web_profiler.yaml",
"config/routes/web_profiler.yaml"
]
},
"symfony/yaml": {
"version": "v6.0.2"
},
"twig/twig": {
"version": "v3.3.7"
},
"webmozart/assert": {
"version": "1.10.0"
},
"willdurand/negotiation": {
"version": "3.0.0"
},
"zendframework/zend-code": {
"version": "3.4.1"
},
"zendframework/zend-eventmanager": {
"version": "3.2.1"
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Tests\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
class GreetingsTest extends ApiTestCase
{
public function testCreateGreeting(): void
{
static::createClient()->request('POST', '/greetings', ['json' => [
'name' => 'Kévin',
]]);
$this->assertResponseStatusCodeSame(201);
$this->assertJsonContains([
'@context' => '/contexts/Greeting',
'@type' => 'Greeting',
'name' => 'Kévin',
]);
}
}

View File

@ -0,0 +1,11 @@
<?php
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
require dirname(__DIR__).'/config/bootstrap.php';
} elseif (method_exists(Dotenv::class, 'bootEnv')) {
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}

View File

@ -1,24 +0,0 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
http_method_override: false
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
#esi: true
#fragments: true
php_errors:
log: true
when@test:
framework:
test: true
session:
storage_factory_id: session.storage.factory.mock_file

View File

@ -1,20 +0,0 @@
<?php
/**
* Fill API backend SQL database with data from government open data.
*/
// CIS_bdpm.txt
// This database holds the list of medicines with status, holder, name, etc.
$URL = "http://localhost/";
function post($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}

View File

@ -1,8 +1,47 @@
version: '3'
version: "3.4"
# Development environment override
services:
php:
build:
target: app_php_dev
volumes:
- ./api:/srv/app
- ./api/docker/php/conf.d/app.dev.ini:/usr/local/etc/php/conf.d/app.dev.ini:ro
# If you develop on Mac or Windows you can remove the vendor/ directory
# from the bind-mount for better performance by enabling the next line:
#- /srv/app/vendor
environment:
# See https://xdebug.org/docs/all_settings#mode
XDEBUG_MODE: "${XDEBUG_MODE:-off}"
extra_hosts:
# Ensure that host.docker.internal is correctly defined on Linux
- host.docker.internal:host-gateway
pwa:
build:
context: ./pwa
target: dev
volumes:
- ./pwa:/srv/app
environment:
API_PLATFORM_CREATE_CLIENT_ENTRYPOINT: http://caddy
API_PLATFORM_CREATE_CLIENT_OUTPUT: .
caddy:
volumes:
- ./api/public:/srv/app/public:ro
- ./api/docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
environment:
MERCURE_EXTRA_DIRECTIVES: demo
###> doctrine/doctrine-bundle ###
database:
ports:
- "5432"
- target: 5432
published: 5432
protocol: tcp
###< doctrine/doctrine-bundle ###
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###

View File

@ -0,0 +1,17 @@
version: "3.4"
# Production environment override
services:
php:
environment:
APP_SECRET: ${APP_SECRET}
MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET}
caddy:
environment:
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
database:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

View File

@ -1,21 +1,90 @@
version: '3'
version: "3.4"
services:
php:
build:
context: ./api
target: app_php
depends_on:
- database
restart: unless-stopped
volumes:
- php_socket:/var/run/php
healthcheck:
interval: 10s
timeout: 3s
retries: 3
start_period: 30s
environment:
DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-14}
TRUSTED_PROXIES: ${TRUSTED_PROXIES:-127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}
TRUSTED_HOSTS: ^${SERVER_NAME:-example\.com|localhost}|caddy$$
MERCURE_URL: ${CADDY_MERCURE_URL:-http://caddy/.well-known/mercure}
MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure
MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
pwa:
build:
context: ./pwa
target: prod
environment:
NEXT_PUBLIC_ENTRYPOINT: http://caddy
caddy:
build:
context: api/
target: app_caddy
depends_on:
- php
- pwa
environment:
PWA_UPSTREAM: pwa:3000
SERVER_NAME: ${SERVER_NAME:-localhost}, caddy:80
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
restart: unless-stopped
volumes:
- php_socket:/var/run/php
- caddy_data:/data
- caddy_config:/config
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
###> doctrine/doctrine-bundle ###
database:
image: postgres:${POSTGRES_VERSION:-14}-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB:-app}
- POSTGRES_DB=${POSTGRES_DB:-app}
# You should definitely change the password in production
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!}
POSTGRES_USER: ${POSTGRES_USER:-app}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-!ChangeMe!}
- POSTGRES_USER=${POSTGRES_USER:-app}
volumes:
- db-data:/var/lib/postgresql/data:rw
# You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
# - ./docker/db/data:/var/lib/postgresql/data:rw
- db_data:/var/lib/postgresql/data
# you may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
# - ./api/docker/db/data:/var/lib/postgresql/data
###< doctrine/doctrine-bundle ###
# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
volumes:
php_socket:
caddy_data:
caddy_config:
###> doctrine/doctrine-bundle ###
db-data:
db_data:
###< doctrine/doctrine-bundle ###
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami/
version: 10.16.2
digest: sha256:61815d0b8e5bbe9bdc0cf3b0b82a9758e1cbdb5c8324c33c450aa25c6d6f9cf4
generated: "2022-06-14T20:46:47.661939283+02:00"

View File

@ -0,0 +1,31 @@
apiVersion: v2
name: api-platform
description: A Helm chart for an API Platform project
home: https://api-platform.com
icon: https://api-platform.com/logo-250x250.png
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 0.1.0
dependencies:
- name: postgresql
version: ~10.16.2
repository: https://charts.bitnami.com/bitnami/
condition: postgresql.enabled

View File

@ -0,0 +1,6 @@
# Deploying to a Kubernetes Cluster
API Platform comes with a native integration with [Kubernetes](https://kubernetes.io/) and the [Helm](https://helm.sh/)
package manager.
[Learn how to deploy in the dedicated documentation entry](https://api-platform.com/docs/deployment/kubernetes/).

View File

@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "api-platform.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "api-platform.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "api-platform.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "api-platform.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -0,0 +1,84 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "api-platform.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "api-platform.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "api-platform.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "api-platform.labels" -}}
helm.sh/chart: {{ include "api-platform.chart" . }}
{{ include "api-platform.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Common labels PWA
*/}}
{{- define "api-platform.labelsPWA" -}}
helm.sh/chart: {{ include "api-platform.chart" . }}
{{ include "api-platform.selectorLabelsPWA" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "api-platform.selectorLabels" -}}
app.kubernetes.io/name: {{ include "api-platform.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ include "api-platform.name" . }}
{{- end }}
{{/*
Selector labels PWA
*/}}
{{- define "api-platform.selectorLabelsPWA" -}}
app.kubernetes.io/name: {{ include "api-platform.name" . }}-pwa
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/part-of: {{ include "api-platform.name" . }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "api-platform.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "api-platform.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "api-platform.fullname" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
data:
php-app-env: {{ .Values.php.appEnv | quote }}
php-app-debug: {{ .Values.php.appDebug | quote }}
php-cors-allow-origin: {{ .Values.php.corsAllowOrigin | quote }}
php-trusted-hosts: {{ .Values.php.trustedHosts | quote }}
php-trusted-proxies: "{{ join "," .Values.php.trustedProxies }}"
mercure-url: "http://{{ include "api-platform.fullname" . }}/.well-known/mercure"
mercure-public-url: {{ .Values.mercure.publicUrl | default "http://127.0.0.1/.well-known/mercure" | quote }}

View File

@ -0,0 +1,172 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "api-platform.fullname" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "api-platform.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "api-platform.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "api-platform.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}-caddy
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.caddy.image.repository }}:{{ .Values.caddy.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.caddy.image.pullPolicy }}
env:
- name: SERVER_NAME
value: :80
- name: PWA_UPSTREAM
value: {{ include "api-platform.fullname" . }}-pwa:3000
- name: MERCURE_PUBLISHER_JWT_KEY
valueFrom:
secretKeyRef:
name: {{ include "api-platform.fullname" . }}
key: mercure-jwt-secret
- name: MERCURE_SUBSCRIBER_JWT_KEY
valueFrom:
secretKeyRef:
name: {{ include "api-platform.fullname" . }}
key: mercure-jwt-secret
ports:
- name: http
containerPort: 80
protocol: TCP
- name: admin
containerPort: 2019
protocol: TCP
volumeMounts:
- mountPath: /var/run/php
name: php-socket
lifecycle:
preStop:
exec:
command: ["curl", "-XPOST", "http://localhost:2019/stop"]
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 3
periodSeconds: 3
resources:
{{- toYaml .Values.resources | nindent 12 }}
- name: {{ .Chart.Name }}-php
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.php.image.repository }}:{{ .Values.php.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.php.image.pullPolicy }}
env:
- name: TRUSTED_HOSTS
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-trusted-hosts
- name: TRUSTED_PROXIES
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-trusted-proxies
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-app-env
- name: APP_DEBUG
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-app-debug
- name: APP_SECRET
valueFrom:
secretKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-app-secret
- name: CORS_ALLOW_ORIGIN
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: php-cors-allow-origin
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ include "api-platform.fullname" . }}
key: database-url
- name: MERCURE_URL
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: mercure-url
- name: MERCURE_PUBLIC_URL
valueFrom:
configMapKeyRef:
name: {{ include "api-platform.fullname" . }}
key: mercure-public-url
- name: MERCURE_JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ include "api-platform.fullname" . }}
key: mercure-jwt-secret
volumeMounts:
- mountPath: /var/run/php
name: php-socket
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "/bin/sleep 1; kill -QUIT 1"]
startupProbe:
exec:
command:
- docker-healthcheck
failureThreshold: 40
periodSeconds: 3
readinessProbe:
exec:
command:
- docker-healthcheck
periodSeconds: 3
livenessProbe:
exec:
command:
- docker-healthcheck
periodSeconds: 3
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: php-socket
emptyDir: {}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "api-platform.fullname" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "api-platform.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "api-platform.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "api-platform.fullname" . }}-pwa
labels:
{{- include "api-platform.labelsPWA" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "api-platform.selectorLabelsPWA" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "api-platform.selectorLabelsPWA" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "api-platform.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}-pwa
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pwa.image.repository }}:{{ .Values.pwa.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.pwa.image.pullPolicy }}
env:
- name: NEXT_PUBLIC_ENTRYPOINT
value: http://{{ include "api-platform.fullname" . }}
ports:
- name: http
containerPort: 3000
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "api-platform.fullname" . }}-pwa
labels:
{{- include "api-platform.labelsPWA" . | nindent 4 }}
spec:
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http
selector:
{{- include "api-platform.selectorLabelsPWA" . | nindent 4 }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "api-platform.fullname" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
type: Opaque
data:
{{- if .Values.postgresql.enabled }}
database-url: {{ printf "pgsql://%s:%s@%s-postgresql/%s?serverVersion=13&charset=utf8" .Values.postgresql.postgresqlUsername .Values.postgresql.postgresqlPassword .Release.Name .Values.postgresql.postgresqlDatabase | b64enc | quote }}
{{- else }}
database-url: {{ .Values.postgresql.url | b64enc | quote }}
{{- end }}
php-app-secret: {{ .Values.php.appSecret | default (randAlphaNum 40) | b64enc | quote }}
mercure-jwt-secret: {{ .Values.mercure.jwtSecret | default (randAlphaNum 40) | b64enc | quote }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "api-platform.fullname" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "api-platform.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "api-platform.serviceAccountName" . }}
labels:
{{- include "api-platform.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "api-platform.fullname" . }}-test-connection"
labels:
{{- include "api-platform.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "api-platform.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@ -0,0 +1,129 @@
# Default values for api-platform.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
php:
image:
repository: "chart-example.local/api-platform/php"
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
appEnv: prod
appDebug: "0"
appSecret: ""
corsAllowOrigin: "^https?://.*?\\.chart-example\\.local$"
trustedHosts: "^127\\.0\\.0\\.1|localhost|.*\\.chart-example\\.local$"
trustedProxies:
- "127.0.0.1"
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
pwa:
image:
repository: "chart-example.local/api-platform/pwa"
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
caddy:
image:
repository: "chart-example.local/api-platform/caddy"
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
# You may prefer using the managed version in production: https://mercure.rocks
mercure:
publicUrl: https://chart-example.local/.well-known/mercure
# Change me!
jwtSecret: "!ChangeMe!"
corsAllowedOrigins: "^https?://.*?\\.chart-example\\.local$"
# Full configuration: https://github.com/bitnami/charts/tree/master/bitnami/postgresql
postgresql:
enabled: true
# If bringing your own PostgreSQL, the full uri to use
url: postgresql://api-platform:!ChangeMe!@database:5432/api?serverVersion=13&charset=utf8
postgresqlUsername: "example"
postgresqlPassword: "!ChangeMe!"
postgresqlDatabase: "api"
# Persistent Volume Storage configuration.
# ref: https://kubernetes.io/docs/user-guide/persistent-volumes
persistence:
enabled: false
pullPolicy: IfNotPresent
image:
repository: bitnami/postgresql
tag: 13
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# If you use Mercure, you need the managed or the On Premise version to deploy more than one pod: https://mercure.rocks/docs/hub/cluster
replicaCount: 1
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}

View File

@ -1 +0,0 @@
*

21
api/pwa/.dockerignore Normal file
View File

@ -0,0 +1,21 @@
**/*.log
**/*.md
**/._*
**/.dockerignore
**/.DS_Store
**/.git/
**/.gitattributes
**/.gitignore
**/.gitmodules
**/docker-compose.*.yaml
**/docker-compose.*.yml
**/docker-compose.yaml
**/docker-compose.yml
**/Dockerfile
**/Thumbs.db
.next/
build/
node_modules/
.editorconfig
.env.*.local
.env.local

Some files were not shown because too many files have changed in this diff Show More