A PHP sample API Structure with basic fundamentals an API needs to get up and running. This codebase demonstrates modern PHP development practices and serves as a foundation for scalable web applications incuding SOLID principles, dependency injection, and enterprise architecture patterns.
- 🏗️ Architecture Overview
- ⚡ Quick Start
- 🔧 Configuration
- 📚 API Documentation
- 🏛️ Architecture Deep Dive
- 🔌 Extension Guide
- 🧪 Testing
- 🛡️ Security
- 📦 Deployment
This API follows Clean Architecture principles with a layered approach:
┌─────────────────────────────────────────────────────────────┐
│ HTTP Layer │
│ Controllers • Middleware • Routes • Request/Response │
├─────────────────────────────────────────────────────────────┤
│ Business Layer │
│ Services • Domain Logic • Validation • Events │
├─────────────────────────────────────────────────────────────┤
│ Persistence Layer │
│ Repositories • Database • Data Access │
├─────────────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│ Configuration • Logging • External Services │
└─────────────────────────────────────────────────────────────┘
- ✅ SOLID Principles - Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
- ✅ Dependency Injection - Custom DI container with automatic resolution
- ✅ Interface-Driven Design - Testable and extensible architecture
- ✅ Service Layer - Clean separation of business logic
- ✅ Repository Pattern - Abstracted data access
- ✅ Middleware Support - Rate limiting, CORS, JWT authentication
- ✅ Comprehensive Logging - Structured logging with context
- ✅ Environment Configuration - 12-factor app compliance
- ✅ Security Best Practices - Authentication, authorization, input validation
- PHP 8.2+
- MySQL 8.0+
- Composer
- Docker (optional but recommended)
- Clone the repository:
git clone <repository-url>
cd frozen-in-time- Start with Docker Compose:
docker-compose up -d- Verify installation:
curl http://api.frozen_in_time.local/v1/health- Install dependencies:
composer install- Configure environment:
cp .env.example .env
# Edit .env with your database credentials- Set up database:
# Create database and tables using provided SQL files
mysql -u root -p < database/init-db.sql
mysql -u root -p EmployeeManagement < database/seeds/sample_data.sql- Configure web server:
- Document root:
public/ - Rewrite all requests to
index.php
- Document root:
# Database Configuration
DB_HOST=mysql
DB_NAME=EmployeeManagement
DB_USERNAME=root
DB_PASSWORD=FrozenInTime2024!
DB_PORT=3306
# Application Configuration
APP_ENV=development
APP_TIMEZONE=UTC
API_VERSION=v1
LOG_LEVEL=INFO
# Security Configuration
JWT_SECRET=your_jwt_secret_here
API_KEY=your_api_key_hereThe API uses JWT-based authentication with department-specific API keys for token generation:
| Department | API Key | Permissions |
|---|---|---|
| Engineering | eng_secure_key_2025 |
create, read, update, delete |
| Human Resources | hr_secure_key_2025 |
create, read, update, delete |
| Finance | fin_secure_key_2025 |
read, update |
| Marketing | mkt_secure_key_2025 |
read |
| Sales | sales_secure_key_2025 |
read |
Authentication Flow:
- Use department + API key to get JWT token via
/v1/auth/token - Include JWT token in Authorization header for all subsequent requests
- Token expires after 1 hour (3600 seconds) - use
/v1/auth/refreshto renew
http://api.frozen_in_time.local/v1
The API uses JWT (JSON Web Token) authentication. First obtain a token, then use it in the Authorization header:
Authorization: Bearer <your_jwt_token>
All responses follow this structure:
{
"success": true|false,
"message": "Readable message",
"data": {...},
"timestamp": "2025-07-18 23:29:09"
}Generate JWT token for authentication.
No authentication required for this endpoint.
Request Body:
{
"department": "Engineering",
"api_key": "eng_secure_key_2025"
}Response:
{
"success": true,
"message": "Token generated successfully",
"data": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"expires_in": 3600,
"token_type": "Bearer",
"department": "Engineering",
"permissions": ["create", "read", "update", "delete"]
}
}Example:
curl -X POST "http://localhost/v1/auth/token" \
-H "Content-Type: application/json" \
-d '{
"department": "Engineering",
"api_key": "eng_secure_key_2025"
}'Refresh an existing JWT token.
Headers:
Authorization: Bearer <your_current_token>
Example:
curl -X POST "http://localhost/v1/auth/refresh" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."Retrieve all employees with pagination.
Headers:
Authorization: Bearer <your_jwt_token>
Query Parameters:
page(int, optional): Page number (default: 1)limit(int, optional): Items per page (default: 50, max: 100)
Response:
{
"success": true,
"message": "Employees retrieved successfully",
"data": {
"data": [
{
"employeeId": "EMP001",
"firstName": "Richard",
"lastName": "Hendricks",
"email": "richard.hendricks@piedpiper.com",
"phone": "+1-650-555-0101",
"department": "Engineering",
"position": "CEO & Founder",
"salary": "150000.00",
"dateOfHire": "2023-01-15",
"status": "active",
"address": "5230 Newell Rd, Palo Alto, CA 94301",
"dateOfBirth": "1985-03-15",
"createdAt": "2025-07-18 18:53:30",
"updatedAt": "2025-07-18 18:53:30"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 13,
"pages": 1
}
}
}Retrieve a specific employee by ID.
Example:
curl -X GET "http://localhost/v1/employees/EMP001" \
-H "Authorization: Bearer <your_jwt_token>"Response:
{
"success": true,
"message": "Employee retrieved successfully",
"data": {
"employeeId": "EMP001",
"firstName": "Richard",
"lastName": "Hendricks",
"email": "richard.hendricks@piedpiper.com",
"department": "Engineering",
"position": "CEO & Founder",
"salary": "150000.00",
"status": "active"
}
}Create a new employee.
Required Permission: create
Headers:
Content-Type: application/json
Authorization: Bearer <your_jwt_token>
Request Body:
{
"employeeId": "EMP014",
"firstName": "Steve",
"lastName": "Wozniak",
"email": "steve.wozniak@apple.com",
"phone": "+1-555-0123",
"department": "Engineering",
"position": "Software Engineer",
"salary": 95000,
"dateOfHire": "2025-07-18",
"address": "123 Tech Street, San Francisco, CA",
"dateOfBirth": "1990-05-15"
}Validation Rules:
employeeId: Required, unique, max 50 charactersfirstName: Required, max 100 characterslastName: Required, max 100 charactersemail: Required, valid email format, max 150 charactersphone: Optional, valid phone format, max 20 charactersdepartment: Required, max 100 charactersposition: Required, max 100 characterssalary: Required, numeric, greater than 0dateOfHire: Required, YYYY-MM-DD format, not in futurestatus: Optional, one of: active, inactive, terminatedaddress: Optional, max 500 charactersdateOfBirth: Optional, YYYY-MM-DD format, not in future
Example:
curl -X POST "http://localhost/v1/employees" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your_jwt_token>" \
-d '{
"employeeId": "EMP014",
"firstName": "Steve",
"lastName": "Wozniak",
"email": "steve.wozniak@apple.com",
"department": "Engineering",
"position": "Software Engineer",
"salary": 95000,
"dateOfHire": "2025-07-18"
}'Update an existing employee.
Required Permission: update
Headers:
Content-Type: application/json
Authorization: Bearer <your_jwt_token>
Request Body: (partial update supported)
{
"salary": 105000,
"position": "Senior Software Engineer"
}Example:
curl -X PUT "http://localhost/v1/employees/EMP014" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your_jwt_token>" \
-d '{
"salary": 105000,
"position": "Senior Software Engineer"
}'Soft delete an employee (sets status to 'deleted').
Required Permission: delete
Example:
curl -X DELETE "http://localhost/v1/employees/EMP014" \
-H "Authorization: Bearer <your_jwt_token>"Response:
{
"success": true,
"message": "Employee deleted successfully",
"data": []
}Search employees with multiple criteria.
Query Parameters:
firstName: Partial match on first namelastName: Partial match on last nameemail: Partial match on emaildepartment: Partial match on departmentposition: Partial match on positionstatus: Exact match on status
Example:
curl -X GET "http://localhost/v1/employees/search?department=Engineering&status=active" \
-H "Authorization: Bearer <your_jwt_token>"Check API health status.
No authentication required.
Response:
{
"success": true,
"message": "Service is healthy",
"data": {
"status": "healthy",
"timestamp": "2025-07-18 23:28:35",
"version": "1.0.0"
}
}{
"success": false,
"message": "Invalid JSON - check your request format",
"timestamp": "2025-07-18 23:29:21"
}{
"success": false,
"message": "Department and API key are required",
"timestamp": "2025-07-18 23:29:21"
}{
"success": false,
"message": "Insufficient permissions",
"timestamp": "2025-07-18 23:29:21"
}{
"success": false,
"message": "Employee not found",
"timestamp": "2025-07-18 23:29:21"
}{
"success": false,
"message": "Validation failed",
"details": {
"validation_errors": [
"Field 'email' is required",
"Salary must be greater than 0"
]
},
"timestamp": "2025-07-18 23:29:21"
}{
"success": false,
"message": "Rate limit exceeded. Too many requests.",
"details": {
"reset_time": 1642534800,
"retry_after": 3600
},
"timestamp": "2025-07-18 23:29:21"
}Headers:
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642534800
Retry-After: 3600
src/
├── bootstrap/ # Application initialization
│ └── app.php # DI container configuration
├── controllers/ # HTTP request handlers
│ └── EmployeeController.php
├── core/ # Framework components
│ └── Container.php # Dependency injection container
├── interfaces/ # Contracts and abstractions
│ ├── EmployeeRepositoryInterface.php
│ ├── EmployeeServiceInterface.php
│ ├── AuthServiceInterface.php
│ ├── ValidatorInterface.php
│ ├── LoggerInterface.php
│ ├── ConfigInterface.php
│ ├── ResponseInterface.php
│ └── RateLimiterInterface.php
├── middleware/ # HTTP middleware
│ └── RateLimitMiddleware.php
├── repositories/ # Data access layer
│ └── EmployeeRepository.php
├── routes/ # URL routing
│ └── api.php
└── services/ # Business logic layer
├── EmployeeService.php
├── AuthService.php
├── ValidatorService.php
├── LoggerService.php
├── ConfigService.php
├── ResponseService.php
└── RateLimiterService.php
1. HTTP Request → public/index.php
2. Bootstrap → src/bootstrap/app.php
3. Container → Dependency resolution
4. Router → src/routes/api.php
5. Middleware → Rate limiting, CORS
6. Controller → HTTP handling
7. Service → Business logic
8. Repository → Database operations
9. Response → JSON output
The custom DI container provides automatic dependency resolution:
// Interface to implementation mapping
$container->singleton(EmployeeServiceInterface::class, EmployeeService::class);
$container->singleton(LoggerInterface::class, LoggerService::class);
// Factory functions for complex objects
$container->singleton(PDO::class, function ($container) {
$config = $container->resolve(ConfigInterface::class);
return new PDO($dsn, $username, $password, $options);
});// Container automatically resolves all dependencies
$controller = $container->resolve(EmployeeController::class);
// Equivalent to:
$config = new ConfigService();
$logger = new LoggerService($config);
$pdo = new PDO(/* config values */);
$repository = new EmployeeRepository($pdo, $logger);
$validator = new ValidatorService();
$employeeService = new EmployeeService($repository, $validator, $logger);
$responseService = new ResponseService();
$authService = new AuthService($config, $logger);
$controller = new EmployeeController($employeeService, $responseService, $logger, $authService);Each class has one reason to change:
EmployeeController: HTTP handlingEmployeeService: Business logicEmployeeRepository: Data accessValidatorService: Input validationLoggerService: Logging
Classes are open for extension, closed for modification:
// Add new authentication method without changing existing code
class LdapAuthService implements AuthServiceInterface {
public function authenticate(string $department, string $apiKey): bool {
// LDAP authentication logic
}
}
// Register in container
$container->singleton(AuthServiceInterface::class, LdapAuthService::class);Implementations can be substituted without breaking functionality:
// Any implementation of LoggerInterface can be used
interface LoggerInterface {
public function info(string $message, array $context = []): void;
}
class FileLogger implements LoggerInterface { /* ... */ }
class DatabaseLogger implements LoggerInterface { /* ... */ }
class CloudLogger implements LoggerInterface { /* ... */ }Clients depend only on interfaces they use:
// Specific, focused interfaces
interface EmployeeRepositoryInterface {
public function create(array $data): bool;
public function getByEmployeeId(string $employeeId): ?array;
// Only repository-specific methods
}
interface ValidatorInterface {
public function validateEmployee(array $data): array;
// Only validation-specific methods
}High-level modules depend on abstractions:
class EmployeeController {
public function __construct(
private EmployeeServiceInterface $service, // ← Abstract
private ResponseInterface $response, // ← Abstract
private LoggerInterface $logger // ← Abstract
) {}
}- Create Interface:
// src/interfaces/NotificationServiceInterface.php
interface NotificationServiceInterface {
public function sendEmail(string $to, string $subject, string $body): bool;
public function sendSms(string $to, string $message): bool;
}- Implement Service:
// src/services/EmailNotificationService.php
class EmailNotificationService implements NotificationServiceInterface {
public function __construct(
private ConfigInterface $config,
private LoggerInterface $logger
) {}
public function sendEmail(string $to, string $subject, string $body): bool {
// Implementation
}
public function sendSms(string $to, string $message): bool {
// Implementation
}
}- Register in Container:
// src/bootstrap/app.php
$container->singleton(NotificationServiceInterface::class, EmailNotificationService::class);- Use in Controllers:
class EmployeeController {
public function __construct(
// ... existing dependencies
private NotificationServiceInterface $notifications
) {}
public function create(): void {
$employee = $this->employeeService->createEmployee($data);
// Send welcome email
$this->notifications->sendEmail(
$employee['email'],
'Welcome to the team!',
"Welcome {$employee['firstName']}!"
);
}
}- Add Controller Method:
// src/controllers/EmployeeController.php
public function getByDepartment(string $department): void {
try {
if (!$this->checkPermission('read')) {
return;
}
$employees = $this->employeeService->getByDepartment($department);
$this->response->success($employees, 'Employees retrieved successfully');
} catch (Exception $e) {
$this->logger->error("Failed to get employees by department", ['error' => $e->getMessage()]);
$this->response->error('Failed to retrieve employees', 500);
}
}- Add Service Method:
// src/services/EmployeeService.php
public function getByDepartment(string $department): array {
return $this->repository->search(['department' => $department]);
}- Add Route:
// src/routes/api.php
case 'GET':
if (count($pathSegments) === 3 && $pathSegments[1] === 'department') {
$controller->getByDepartment($pathSegments[2]);
}
break;- Create New Auth Service:
interface JwtAuthServiceInterface {
public function generateToken(array $claims): string;
public function validateToken(string $token): ?array;
}
class JwtAuthService implements JwtAuthServiceInterface {
public function __construct(
private ConfigInterface $config,
private LoggerInterface $logger
) {}
public function generateToken(array $claims): string {
// JWT implementation
}
public function validateToken(string $token): ?array {
// JWT validation
}
}- Register in Container:
$container->singleton(JwtAuthServiceInterface::class, JwtAuthService::class);- Create Middleware:
class JwtMiddleware {
public function __construct(
private JwtAuthServiceInterface $jwt,
private ResponseInterface $response
) {}
public function handle(): bool {
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!$token || !$this->jwt->validateToken($token)) {
$this->response->unauthorized('Invalid token');
return false;
}
return true;
}
}- Create Migration File:
-- database/migrations/2025_07_18_add_employee_notes.sql
ALTER TABLE Employees
ADD COLUMN notes TEXT NULL
AFTER address;- Update Repository:
// Add to EmployeeRepository::create()
$sql = "INSERT INTO Employees (..., notes) VALUES (..., :notes)";- Update Service Validation:
// Add to ValidatorService::validateEmployee()
if (isset($data['notes']) && strlen($data['notes']) > 1000) {
$errors[] = "Notes must be 1000 characters or less";
}- Create Event System:
interface EventDispatcherInterface {
public function dispatch(object $event): void;
public function listen(string $eventClass, callable $listener): void;
}
class EventDispatcher implements EventDispatcherInterface {
private array $listeners = [];
public function dispatch(object $event): void {
$eventClass = get_class($event);
foreach ($this->listeners[$eventClass] ?? [] as $listener) {
$listener($event);
}
}
public function listen(string $eventClass, callable $listener): void {
$this->listeners[$eventClass][] = $listener;
}
}- Create Events:
class EmployeeCreatedEvent {
public function __construct(
public readonly array $employee,
public readonly string $createdBy
) {}
}- Dispatch Events:
// In EmployeeService::createEmployee()
$employee = $this->repository->create($data);
$this->eventDispatcher->dispatch(new EmployeeCreatedEvent($employee, $department));- Register Listeners:
// In bootstrap/app.php
$eventDispatcher = $container->resolve(EventDispatcherInterface::class);
$eventDispatcher->listen(EmployeeCreatedEvent::class, function($event) use ($container) {
$notifications = $container->resolve(NotificationServiceInterface::class);
$notifications->sendEmail($event->employee['email'], 'Welcome!', '...');
});Our comprehensive testing suite features using Silicon Valley characters, making tests both technically robust and entertaining to read!
Instead of boring technical tests, we shall use relatable scenarios:
- Richard Hendricks creating employee records at Pied Piper
- Gavin Belson trying (and failing) to access Pied Piper data
- Dinesh Chugtai getting promoted to Senior Engineer
- HR department managing team permissions
- Marketing team discovering their read-only limitations
# Run all tests with human-readable output
vendor/bin/phpunit --testdox
# Run unit tests only (recommended for development)
vendor/bin/phpunit tests/Unit --testdox
# Run integration tests only
vendor/bin/phpunit tests/Integration --testdox
# Run specific test class
vendor/bin/phpunit tests/Unit/Services/ValidatorServiceTest.php
# Run specific test method
vendor/bin/phpunit tests/Unit/Services/ValidatorServiceTest.php --filter=it_validates_phone_numbers_properly
# Run with coverage (if xdebug installed)
vendor/bin/phpunit --coverage-html tests/results/coverage
# Generate test documentation in HTML format
vendor/bin/phpunit --testdox-html tests/results/testdox.html
# Run tests and generate both coverage and documentation
vendor/bin/phpunit --testdox-html tests/results/testdox.html --coverage-html tests/results/coverage✅ Unit Tests: 49 tests, 125 assertions - ALL PASSING
📋 AuthService: 12 tests (authentication & permissions)
👥 EmployeeService: 11 tests (business logic)
✓ ValidatorService: 14 tests (input validation & XSS prevention)
🗄️ EmployeeRepository: 12 tests (database operations)
⚙️ Integration Tests: Controller behavior testing
🎯 Human-Readable: TestDox format for clear documentationtests/
├── Unit/ # Isolated component testing
│ ├── Services/
│ │ ├── AuthServiceTest.php # 🔐 Department permissions
│ │ ├── EmployeeServiceTest.php # 👥 Business logic
│ │ └── ValidatorServiceTest.php # ✅ Input validation
│ └── Repositories/
│ └── EmployeeRepositoryTest.php # 🗄️ Database operations
├── Integration/ # End-to-end behavior testing
│ ├── Controllers/
│ │ └── EmployeeControllerTest.php # 🎮 Controller integration
│ └── ApiRoutesIntegrationTest.php # 🌐 Full API testing
└── bootstrap.php # Test environment setup
/** @test */
public function richard_can_successfully_add_jared_to_the_team(): void
{
// Given Richard (Engineering) wants to add Jared to the team
$jaredData = [
'firstName' => 'Jared',
'lastName' => 'Dunn',
'email' => 'jared.dunn@piedpiper.com',
'department' => 'Operations',
'position' => 'Head of Business Development',
'salary' => 110000,
'dateOfHire' => '2023-07-19'
];
// And authentication succeeds
$this->mockAuthService->shouldReceive('authenticate')
->with('Engineering', 'eng_secure_key_2025')
->andReturn(true);
// And the service successfully creates Jared
$this->mockEmployeeService->shouldReceive('createEmployee')
->with($jaredData)
->andReturn(array_merge($jaredData, [
'employeeId' => 'EMP005',
'status' => 'active'
]));
// When Richard creates Jared's employee record
$this->controller->create();
// Then all expectations should be met ✅
}/** @test */
public function gavin_cannot_access_pied_piper_data_with_wrong_credentials(): void
{
// Given Gavin from Hooli tries to spy on our employee data
// When he uses wrong credentials
// Then he should be denied access 🚫
}
/** @test */
public function it_sanitizes_input_to_prevent_xss_attacks(): void
{
// Given someone tries XSS injection
$maliciousInput = '<script>alert("Gavin was here")</script>Richard';
// When we sanitize the input
$result = $this->validator->sanitizeInput($maliciousInput);
// Then the script should be stripped
$this->assertEquals('Richard', $result);
}The test environment automatically:
- ✅ Sets up proper test database configuration
- ✅ Initializes dependency injection container for integration tests
- ✅ Creates Silicon Valley test employee data
- ✅ Handles test isolation and cleanup
- ✅ Provides structured logging for debugging
// Test employees automatically created for integration tests:
[
'TEST001' => 'Richard Hendricks - CEO & Founder',
'TEST002' => 'Bertram Gilfoyle - System Architect',
'TEST003' => 'Dinesh Chugtai - Senior Software Engineer'
]# Test database connection with Docker
docker exec frozen_in_time php run-tests.php
# Expected output:
# 🧪 Test environment initialized for SOLID architecture
# ✅ All 49 unit tests passing
# 🎭 Human-like scenarios verified
# 🔐 Security validations confirmed- 🎭 Human-Readable Tests - Scenarios anyone can understand
- 🔒 Security-First - XSS prevention, authentication testing
- ⚡ Fast Execution - Unit tests run in milliseconds
- 🧩 Isolated Components - True unit testing with mocks
- 📊 Comprehensive Coverage - All SOLID components tested
- 🛡️ Error Handling - Graceful failure testing
- 📝 Documentation - TestDox output serves as living docs
- Department-based access control
- API key authentication
- Permission-based operations (create, read, update, delete)
- Rate limiting per endpoint and client
- Comprehensive validation for all employee fields
- SQL injection prevention using prepared statements
- XSS protection through input sanitization
- Type checking with PHP 8.2+ strict types
// CORS headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, X-Department, X-API-Key
// Rate limiting headers
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1642534800- Sensitive data stored in environment variables
- Database passwords not logged (security fix applied)
- API keys configurable per environment
- Debug mode disabled in production
- Build production image:
docker build -t frozen-in-time:production .- Run with production environment:
docker run -d \
--name frozen-in-time-prod \
-p 80:80 \
-e APP_ENV=production \
-e LOG_LEVEL=ERROR \
frozen-in-time:productionAPP_ENV=development
LOG_LEVEL=DEBUG
DB_HOST=localhostAPP_ENV=staging
LOG_LEVEL=INFO
DB_HOST=staging-db.company.comAPP_ENV=production
LOG_LEVEL=ERROR
DB_HOST=prod-db.company.com# Application health
curl http://api.company.com/v1/health
# Database connectivity
curl http://api.company.com/v1/health/database- Application logs:
/var/www/html/logs/app.log - Error tracking: Structured JSON logs with context
- Performance metrics: Request timing and memory usage
- Rate limiting: Monitor API usage patterns
- PSR-4 autoloading
- PSR-12 coding style
- PHPDoc comments for all public methods
- Type declarations for all parameters and return values
- SOLID principles adherence
- Create feature branch from
main - Write tests for new functionality
- Ensure all tests pass
- Update documentation
- Submit pull request with clear description
# Install development dependencies
composer install --dev
# Run code style checks
vendor/bin/phpcs src/
# Run static analysis
vendor/bin/phpstan analyse src/
# Format code
vendor/bin/phpcbf src/- Documentation: This README
- Issues: GitHub Issues
- Architecture Questions: See "Architecture Deep Dive" section
- API Questions: See "API Documentation" section
MIT License - see LICENSE file for details.
Happy Coding 🥳