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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ workflows:
filters: # required since `deploy-prod` has tag filters AND requires `build`
tags:
only: /^v.*/
# baseUrl for cypress is set in cypress.json (currently staging.boxtribute.org)
# baseUrl for cypress is set in cypress.config.js (currently staging.boxtribute.org)
- cypress/run:
name: cypress-feature-tests
package-manager: yarn
Expand Down
2 changes: 1 addition & 1 deletion .docker/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM php:8.2-apache
RUN a2enmod rewrite
# install needed libraries
RUN apt-get update \
&& apt-get -y --no-install-recommends install libfontconfig1 libxrender1 libxext6 zlib1g-dev libpng-dev libfreetype6-dev libjpeg62-turbo-dev \
&& apt-get -y --no-install-recommends install libfontconfig1 libxrender1 libxext6 zlib1g-dev libpng-dev libfreetype6-dev libjpeg62-turbo-dev zip unzip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# PHP extensions
Expand Down
183 changes: 183 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Dropapp - Boxtribute v1 Web Application

Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.

Dropapp is a PHP web application for managing donated goods distribution to refugees and people in need. It uses PHP 8.2+, MySQL, Smarty templates, Auth0 authentication, Docker for local development, and Cypress for browser testing.

## General Instructions

**Think first and make a plan before you start implementing.** Always analyze the problem, understand the codebase, and create a clear implementation plan before making any changes.

**CRITICAL**: NEVER modify `.circleci/config.yml` or trigger any deployment manually. If changes to CI configuration are absolutely necessary, request approval in a PR comment.

**Always report issues with building/testing in the PR.** If you encounter build failures, test failures, or other issues during development, document them clearly in your progress reports so stakeholders are aware of any blockers or limitations.

## Working Effectively

### Bootstrap and Install Dependencies
**The environment is already prepared through the Copilot Setup Steps.**
- verify that the MySQL database is running on localhost:9906 (`nc -z localhost 9906`)
- verify that the file `library/config.php` is present

### Running the Application

#### Option 1: PHP Development Server (RECOMMENDED)
```bash
php -S localhost:8000 gcloud-entry.php
```
- Application accessible at http://localhost:8000/
- Lightweight, reliable for development
- ALWAYS use this method when Docker fails

#### Option 2: Docker (MAY FAIL)
```bash
docker compose up --build
```
- Takes 5-15 minutes for initial build. NEVER CANCEL. Set timeout to 20+ minutes.
- Application accessible at http://localhost:8100/
- Docker build may fail on xdebug installation - this is a known issue
- Use PHP dev server if Docker fails

### Database Setup
**Through the Copilot Setup Steps, the database is already set up and the migrations have run.**

General database information:
- Database config in `phinx.yml`
- Initial seed data available in `db/init.sql` (2700+ lines)

**CRITICAL Database Configuration for PHP Development Server:**
- The default `library/config.php` only works in Docker containers
- For PHP development server, these environment variables must be set (they are already configured)
```bash
MYSQL_HOST=127.0.0.1
MYSQL_PORT=9906
```
## Linting and Code Quality

### PHP Syntax Checking
```bash
vendor/bin/parallel-lint --exclude vendor .
```
- Takes ~1.4 seconds. NEVER CANCEL. Set timeout to 30+ seconds.
- Checks all PHP files for syntax errors

### Code Formatting
```bash
php vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix . --dry-run --verbose --rules @PhpCsFixer
```
- Takes ~14 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
- Shows formatting issues without fixing them
- Remove `--dry-run` to actually fix issues
- Generated Smarty templates in `templates/templates_c/` will show formatting issues - this is normal

### Auto-fix Code Style
```bash
php vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix . --rules @PhpCsFixer
```
- Takes ~15 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
- Required before committing to pass CI

## Testing

### Cypress Browser Tests
**You don't have to install Cypress, it's already prepared through the Copilot Setup Steps.**

Verify that Cypress is available:
```bash
yarn cypress version # Check installation status
```

Browser test structure:
- `cypress/e2e/1_feature_tests/` - Feature and UI tests
- `cypress/e2e/2_auth_tests/` - Authentication and user management tests

### Running Cypress Tests
```bash
CYPRESS_baseUrl=http://localhost:8000 yarn run cypress --spec 'cypress/e2e/1_feature_tests/*.js' --env 'auth0Domain=boxtribute-dev.eu.auth0.com'
```
- Runs Cypress with baseUrl set to http://localhost:8000 and auth0Domain set to the development tenant
- Requires the application to be running on localhost:8000 (local PHP setup)
- Requires Cypress binary to be installed

Test user credentials (when Auth0 is configured):
- admin@admin.co / Browser_tests
- coordinator@coordinator.co / Browser_tests
- user@user.co / Browser_tests

## Validation

### Manual Application Testing
After making changes, ALWAYS test the following scenarios:

1. **Start the application** using PHP dev server: `php -S localhost:8000 gcloud-entry.php`
2. **Access the homepage** at http://localhost:8000/
3. **Verify basic page loading** - should see Boxtribute interface or database connection error
4. **Test error handling** - visit non-existent page to check error display
5. **Check console/logs** for PHP errors or warnings

**NOTE:** Complete development environment now includes:
- ✅ MySQL database on localhost:9906 with successful migrations
- ✅ Auth0 authentication with working login form
- ✅ PHP development server with full database connectivity
- ✅ Asset compilation (100+ Smarty templates)

### Pre-commit Validation
ALWAYS run these commands before committing:
```bash
vendor/bin/parallel-lint --exclude vendor .
php vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix . --rules @PhpCsFixer
php build.php
```

## Common Issues and Workarounds

### Composer State Issues
- If you get "uncommitted changes" errors, run: `rm -rf vendor/ && composer install`
- This clears any problematic vendor directory state

### Docker Build Failures
- Xdebug installation often fails in Docker environment
- Use PHP development server instead: `php -S localhost:8000 gcloud-entry.php`

### Generated Template Formatting
- Smarty compiled templates in `templates/templates_c/` show CS Fixer violations
- These are auto-generated files - formatting issues are normal and expected
- Do not manually edit these files

## Key Project Structure

```
dropapp/
├── README.md # Main documentation
├── CONTRIBUTING.md # Contribution guidelines
├── composer.json # PHP dependencies
├── package.json # Node.js dependencies
├── docker-compose.yml # Docker configuration
├── build.php # Build script for assets/templates
├── phinx.yml # Database migration config
├── library/ # Core PHP application code
│ ├── config.php.default # Configuration template
│ ├── functions.php # Utility functions
│ └── core.php # Application core
├── db/ # Database files
│ ├── init.sql # Initial database seed
│ └── migrations/ # Phinx migration files
├── templates/ # Smarty template files
├── assets/ # CSS, JS, images
├── cypress/ # Browser test files (if available)
└── .circleci/ # CI/CD configuration
```

## Time Estimates and Timeouts

- **Composer install (production):** 30-60 seconds - timeout: 90+ seconds
- **Composer install (dev):** 60-120 seconds - timeout: 180+ seconds
- **Build process:** 1 second - timeout: 30+ seconds
- **PHP linting:** 1.4 seconds - timeout: 30+ seconds
- **Code formatting:** 14 seconds - timeout: 60+ seconds
- **Database migration:** 10-30 seconds - timeout: 60+ seconds
- **Docker database startup:** 30-120 seconds - timeout: 180+ seconds
- **Docker build:** 5-15 minutes - timeout: 20+ minutes
- **yarn install:** 20-60 seconds - timeout: 120+ seconds (with Cypress binary)

**CRITICAL:** Always use the specified timeouts. NEVER CANCEL long-running operations prematurely.
9 changes: 5 additions & 4 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ on:
branches:
- master
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
branches:
- master

jobs:
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
Expand Down Expand Up @@ -44,19 +44,20 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache: 'yarn'

- name: Install dependencies
run: |
php --version
curl -s https://getcomposer.org/installer | php
mv composer.phar composer
./composer install -n
rm composer

- name: Install testing dependencies
run: |
node --version
npm install
yarn install
npx cypress version

- name: Start MySQL database
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ to launch a shell inside the Docker container and run the phinx commands there.
We use [Cypress](https://www.cypress.io) for Browser-test. To run Cypress tests on your local environment, please

1. [Install Cypress via direct Download](https://docs.cypress.io/guides/getting-started/installing-cypress.html#Direct-download)
2. Set the variable `baseURL` to your local address, e.g. `localhost:8100` in cypress.json.
3. Set the env variable `auth0Domain` to the development Auth0 tenant,
e.g. `boxtribute-dev.eu.auth0.com` in cypress.json.
2. Set the variable `baseURL` to your local address, e.g. `localhost:8100` in `cypress.config.js`.
3. In the same file, set the env variable `auth0Domain` to the development Auth0 tenant,
e.g. `boxtribute-dev.eu.auth0.com`
4. Open Cypress and this repo in Cypress

#### Cypress Tests fail due to unsynchronized users with Auth0
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"allow-plugins": {
"php-http/discovery": true,
"tbachert/spi": true
}
},
"process-timeout": 1800
}
}
18 changes: 10 additions & 8 deletions library/config.php.default
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?php
// auth0
$settings['auth0_api_id'] = '';
$settings['auth0_api_id'] = getenv('AUTH0_API_ID') ?: '';
$settings['auth0_api_domain'] = 'boxtribute-dev.eu.auth0.com';
$settings['auth0_domain'] = 'boxtribute-dev.eu.auth0.com';
$settings['auth0_client_id'] = '';
$settings['auth0_db_connection_id'] = '';
$settings['auth0_client_secret'] = '';
$settings['auth0_cookie_secret'] = '';
$settings['auth0_redirect_uri'] = 'http://localhost:8100';
$settings['auth0_api_audience'] = '';
$settings['auth0_client_id'] = getenv('AUTH0_CLIENT_ID') ?: '';
$settings['auth0_db_connection_id'] = getenv('AUTH0_DB_CONNECTION_ID') ?: '';
$settings['auth0_client_secret'] = getenv('AUTH0_CLIENT_SECRET') ?: '';
$settings['auth0_cookie_secret'] = getenv('AUTH0_COOKIE_SECRET') ?: '';
$settings['auth0_redirect_uri'] = getenv('AUTH0_REDIRECT_URI') ?: 'http://localhost:8100';
$settings['auth0_api_audience'] = 'boxtribute-dev-api';

$settings['app_env'] = 'development';
$settings['test_pwd'] = 'Browser_tests';
Expand All @@ -20,7 +20,9 @@
// $settings['db_socket'] = '/cloudsql/dropapp-XYZ:europe-west1:dropapp-ABC';
// when just running locally
$settings['db_database'] = 'dropapp_dev';
$settings['db_host'] = 'db_mysql';
// default configuration is for the 'web' docker-compose service
$settings['db_host'] = getenv('MYSQL_HOST') ?: 'db_mysql';
$settings['db_port'] = getenv('MYSQL_PORT') ?: '3306';
$settings['db_user'] = 'root';
$settings['db_pass'] = 'dropapp_root';

Expand Down
3 changes: 3 additions & 0 deletions library/core.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ function () use ($bypassAuthentication, $mobile, $ajax) {
$db_dsn = 'mysql:dbname='.$settings['db_database'].';unix_socket='.$settings['db_socket'];
} else {
$db_dsn = 'mysql:host='.$settings['db_host'].';dbname='.$settings['db_database'];
if (array_key_exists('db_port', $settings)) {
$db_dsn .= ';port='.$settings['db_port'];
}
}
db_connect($db_dsn, $settings['db_user'], $settings['db_pass']);

Expand Down