diff --git a/.env b/.env index 99cf724..660adfd 100644 --- a/.env +++ b/.env @@ -2,9 +2,9 @@ NGINX_IMAGE=nginx:stable-alpine # Backend -APP_IMAGE=split-fairly-dev:0.1.1 +APP_IMAGE=split-fairly-dev:0.1.2 APP_NAME=split-fairly -APP_VERSION=0.1.1 +APP_VERSION=0.1.2 APP_ENV=dev ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=secret diff --git a/Makefile b/Makefile index 1ea284a..2c08afa 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,10 @@ APP_NAME = split-fairly -VERSION = 0.1.1 +VERSION = 0.1.2 .DEFAULT_GOAL := help +.PHONY: build prod start + help: @echo "📋 Available targets:\n" @echo "🏗️ Build & Setup:" diff --git a/README.md b/README.md index 384ebe0..d82a909 100644 --- a/README.md +++ b/README.md @@ -91,22 +91,19 @@ Visit `http://localhost:8000` in your browser. # Build production images make prod -# Deploy to cluster -helm install app ./helm +# Deploy with 3 app pods + 2 worker pods +helm install app ./helm --set replicaCount.app=3 --set replicaCount.worker=2 # or: helm upgrade --install app ./helm -# Watch pods come up -kubectl get pods -w - -# View logs for all pods with the PHP label (app + worker) -kubectl logs -f -l technology=php - # Access the application via NodePort: # Link: http://localhost:30190 # Or configure port forwarding via: kubectl port-forward svc/app-split-fairly-web 8080:80 # Link: http://localhost:8080 + +# View logs for all pods with the PHP label (app + worker) +kubectl logs -f -l technology=php ``` ### Kubernetes Architecture diff --git a/backend/public/favicon.svg b/backend/public/favicon.svg new file mode 100644 index 0000000..7fe3bde --- /dev/null +++ b/backend/public/favicon.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/backend/src/Controller/Admin/EventCrudController.php b/backend/src/Controller/Admin/EventCrudController.php index 922b107..a8b60fa 100644 --- a/backend/src/Controller/Admin/EventCrudController.php +++ b/backend/src/Controller/Admin/EventCrudController.php @@ -2,8 +2,9 @@ namespace App\Controller\Admin; -use App\Entity\Event; +use App\Entity\Event as EventEntity; use App\Form\DataTransformer\JsonToStringTransformer; +use App\SplitFairly\EventStoreInterface; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; @@ -16,9 +17,11 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\Security\Http\Attribute\IsGranted; /** - * @extends AbstractCrudController + * @extends AbstractCrudController * * Admin interface for viewing and managing domain events stored in event sourcing. * Most event fields are immutable (id, createdAt, createdBy, subjectType, subjectId, eventType), @@ -28,7 +31,11 @@ class EventCrudController extends AbstractCrudController { public static function getEntityFqcn(): string { - return Event::class; + return EventEntity::class; + } + + public function __construct(private EventStoreInterface $eventRepository) + { } public function configureCrud(Crud $crud): Crud @@ -45,9 +52,14 @@ public function configureCrud(Crud $crud): Crud public function configureActions(Actions $actions): Actions { + $wipe = Action::new('wipeEvents', 'Wipe Events', 'fa fa-trash') + ->addCssClass('btn btn-danger') + ->linkToCrudAction('wipeEvents'); + return $actions ->remove(Crud::PAGE_INDEX, Action::NEW) - ->add(Crud::PAGE_INDEX, Action::DETAIL); + ->add(Crud::PAGE_INDEX, Action::DETAIL) + ->add(Crud::PAGE_INDEX, $wipe); } public function configureFields(string $pageName): iterable @@ -113,4 +125,17 @@ private function addPayloadField(FormBuilderInterface $builder): void $builder->get('payload')->addModelTransformer(new JsonToStringTransformer()); } + + /** @param AdminContext $context */ + #[IsGranted('ROLE_ADMIN')] + public function wipeEvents(AdminContext $context): RedirectResponse + { + $this->eventRepository->reset(); + $this->addFlash('success', 'All events have been deleted.'); + + $referrer = $context->getRequest()->headers->get('referer'); + $route = $referrer ?? $this->generateUrl('admin_event_index'); + + return $this->redirect($route); + } } diff --git a/backend/templates/base.html.twig b/backend/templates/base.html.twig index d7b29d4..11851e6 100644 --- a/backend/templates/base.html.twig +++ b/backend/templates/base.html.twig @@ -4,6 +4,7 @@ {% block title %}Split Fairly{% endblock %} + {% block stylesheets %} diff --git a/build/php/Dockerfile b/build/php/Dockerfile index df4b4d0..c4611ff 100644 --- a/build/php/Dockerfile +++ b/build/php/Dockerfile @@ -26,7 +26,7 @@ WORKDIR /var/www/project RUN apk add --no-cache --virtual .build-deps \ build-base autoconf icu-dev libzip-dev \ - && apk add --no-cache libintl git zip icu-libs \ + && apk add --no-cache libintl git zip libzip icu-libs \ && docker-php-ext-configure intl \ && docker-php-ext-install intl pdo opcache pdo_mysql zip \ && pecl install opentelemetry redis \ diff --git a/frontend/favicon.svg b/frontend/favicon.svg new file mode 100644 index 0000000..7fe3bde --- /dev/null +++ b/frontend/favicon.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html index cb765ea..3e48ba8 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -8,7 +8,7 @@ 💰 Split Fairly - +
diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 211e903..6a37e8e 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: split-fairly description: Helm chart for the split-fairly application type: application -version: 0.1.0 -appVersion: "0.1.1" +version: 0.1.2 +appVersion: "0.1.2" keywords: - split-fairly - web diff --git a/helm/values.yaml b/helm/values.yaml index 7a64dc0..c20654d 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -6,11 +6,11 @@ replicaCount: image: app: repository: "split-fairly" - tag: "0.1.1" + tag: "0.1.2" pullPolicy: IfNotPresent web: repository: "split-fairly-web" - tag: "0.1.1" + tag: "0.1.2" pullPolicy: IfNotPresent mysql: repository: "mysql" @@ -42,7 +42,7 @@ resources: env: APP_SECRET: "F3E46580-5F9A-4524-B218-90490B033192" APP_ENV: "prod" - APP_VERSION: "0.1.1" + APP_VERSION: "0.1.2" DATABASE_URL: "mysql://{{ .Values.mysql.user }}:{{ .Values.mysql.password }}@{{ include \"split-fairly.fullname\" . }}-db:{{ .Values.service.mysql.port }}/{{ default \"app\" .Values.mysql.database }}?serverVersion=8.0.31&charset=utf8mb4" ADMIN_EMAIL: "admin@example.com" ADMIN_PASSWORD: "secret"