Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

PANDA API (Portfolio Arrangement: Nest of Digitalized Assets) is a Symfony 7.3+ based portfolio management API using Domain-Driven Design (DDD) with bounded contexts and hexagonal architecture.

## Key Commands

### Development with Docker
- `make install` - Complete setup (build, run, setup JWT keys)
- `make build` - Build Docker images
- `make run` - Start containers
- `make stop` - Stop containers
- `docker compose exec php bash` - Access PHP container shell

### Testing
- `vendor/bin/phpunit --testsuite unit` - Unit tests only
- `vendor/bin/phpunit --testsuite contract` - Contract tests only
- `vendor/bin/phpspec run` - PHPSpec behavioral tests
- `vendor/bin/behat --strict --no-interaction -f progress` - Behat acceptance tests

### Code Quality
- `composer static-analyze:phpstan` - Run PHPStan static analysis
- `composer static-analyze:code-style` - Check code style (dry-run)
- `composer fix:code-style` - Fix code style issues

## Architecture

### Bounded Contexts
The application is organized into distinct bounded contexts:

- **Account** - User management and authentication
- **Trade** - Asset and transaction management
- **Exchange** - Exchange rate management (live rates and historical logs)
- **Portfolio** - Portfolio and portfolio item management
- **Report** - Report generation and file management
- **Core** - Shared infrastructure and common patterns

### Anti-Corruption Layers (ACL)
- **PortfolioACL/Trade** - Handles portfolio updates when trade events occur
- **TradeACL/Exchange** - Ensures exchange rate integrity for transactions

### Architectural Patterns
- **Hexagonal Architecture** - Each bounded context follows ports and adapters pattern
- **CQRS** - Command Query Responsibility Segregation with separate handlers
- **Event-Driven** - Domain events for cross-context communication
- **Repository Pattern** - Abstract data access with Doctrine ORM implementation

### Layer Structure (per bounded context)
- `Application/` - Commands, queries, handlers, and application services
- `Domain/` - Business logic, entities, value objects, domain events
- `Infrastructure/` - External concerns (API, database, configuration)

### Key Infrastructure Components
- **Symfony 7.3+** - Framework
- **API Platform 4.0+** - REST API with OpenAPI documentation
- **Doctrine ORM** - Database persistence with PostgreSQL
- **JWT Authentication** - Token-based API authentication
- **Docker** - Containerized development environment

## Configuration Structure
Configuration is centralized in `src/Core/Infrastructure/Configuration/Symfony/` with package-specific configs in the `Package/` subdirectory.

## Testing Strategy
- **Unit Tests** (`tests/App/`) - Domain logic testing
- **Contract Tests** (`tests/Api/`) - API endpoint testing with fixtures
- **Behavioral Tests** (`spec/`) - PHPSpec behavior specification
- **Acceptance Tests** (`features/`, `tests/Behat/`) - Gherkin-based feature testing
- **Architecture Tests** (`tests/Architecture/`) - Enforce architectural boundaries

## Development Notes
- JWT keys must be generated after initial setup
- All tested API responses (contracts) have corresponding JSON files in `responses/api/`
- Database migrations are in `migrations/` directory
- All data fixtures loaded in API (contract) tests are in `fixtures/api/`
- PHPStan is configured with max level analysis
- Code style is enforced with PHP CS Fixer
56 changes: 28 additions & 28 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,37 @@
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0",
"api-platform/core": "^4.0",
"composer/package-versions-deprecated": "1.11.99.5",
"doctrine/annotations": "^2.0",
"doctrine/doctrine-bundle": "^2.7",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.12",
"gedmo/doctrine-extensions": "^3.11",
"guzzlehttp/guzzle": "^7.4",
"lexik/jwt-authentication-bundle": "^2.18",
"lexik/jwt-authentication-bundle": "^3.1",
"nelmio/cors-bundle": "^2.2",
"phpstan/phpdoc-parser": "^1.16",
"stof/doctrine-extensions-bundle": "^1.12",
"symfony/asset": "^6.4",
"symfony/console": "^6.4",
"symfony/dotenv": "^6.4",
"symfony/expression-language": "^6.4",
"symfony/asset": "^7.3",
"symfony/console": "^7.3",
"symfony/dotenv": "^7.3",
"symfony/expression-language": "^7.3",
"symfony/flex": "^2.2",
"symfony/framework-bundle": "^6.4",
"symfony/messenger": "^6.4",
"symfony/mime": "^6.4",
"symfony/framework-bundle": "^7.3",
"symfony/messenger": "^7.3",
"symfony/mime": "^7.3",
"symfony/monolog-bundle": "^3.8",
"symfony/property-access": "^6.4",
"symfony/property-info": "^6.4",
"symfony/runtime": "^6.4",
"symfony/security-bundle": "^6.4",
"symfony/serializer": "^6.4",
"symfony/string": "^6.4",
"symfony/twig-bundle": "^6.4",
"symfony/uid": "^6.4",
"symfony/validator": "^6.4",
"symfony/yaml": "^6.4"
"symfony/property-access": "^7.3",
"symfony/property-info": "^7.3",
"symfony/runtime": "^7.3",
"symfony/security-bundle": "^7.3",
"symfony/serializer": "^7.3",
"symfony/string": "^7.3",
"symfony/twig-bundle": "^7.3",
"symfony/uid": "^7.3",
"symfony/validator": "^7.3",
"symfony/yaml": "^7.3"
},
"require-dev": {
"api-platform/schema-generator": "^5.0",
Expand All @@ -49,15 +49,15 @@
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/extension-installer": "^1.2",
"phpstan/phpstan": "^1.9",
"symfony/browser-kit": "^6.4",
"symfony/css-selector": "^6.4",
"symfony/debug-bundle": "^6.4",
"symfony/http-client": "^6.4",
"symfony/browser-kit": "^7.3",
"symfony/css-selector": "^7.3",
"symfony/debug-bundle": "^7.3",
"symfony/http-client": "^7.3",
"symfony/maker-bundle": "^1.44",
"symfony/phpunit-bridge": "^6.4",
"symfony/stopwatch": "^6.4",
"symfony/var-dumper": "^6.4",
"symfony/web-profiler-bundle": "^6.4"
"symfony/phpunit-bridge": "^7.3",
"symfony/stopwatch": "^7.3",
"symfony/var-dumper": "^7.3",
"symfony/web-profiler-bundle": "^7.3"
},
"config": {
"optimize-autoloader": true,
Expand Down Expand Up @@ -125,7 +125,7 @@
"extra": {
"symfony": {
"allow-contrib": false,
"require": "^6.4"
"require": "^7.3"
}
}
}
Loading