Initial commit
This commit is contained in:
commit
c29badf6b7
59 changed files with 1563 additions and 0 deletions
24
.editorconfig
Normal file
24
.editorconfig
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{js,jsx,ts,tsx,vue}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[docker-compose.yml]
|
||||||
|
indent_size = 2
|
||||||
76
.env.example
Normal file
76
.env.example
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
APP_NAME="Core PHP App"
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_TIMEZONE=UTC
|
||||||
|
APP_URL=http://localhost
|
||||||
|
|
||||||
|
APP_LOCALE=en_GB
|
||||||
|
APP_FALLBACK_LOCALE=en_GB
|
||||||
|
APP_FAKER_LOCALE=en_GB
|
||||||
|
|
||||||
|
APP_MAINTENANCE_DRIVER=file
|
||||||
|
|
||||||
|
BCRYPT_ROUNDS=12
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_STACK=single
|
||||||
|
LOG_DEPRECATIONS_CHANNEL=null
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
DB_CONNECTION=sqlite
|
||||||
|
# DB_HOST=127.0.0.1
|
||||||
|
# DB_PORT=3306
|
||||||
|
# DB_DATABASE=core
|
||||||
|
# DB_USERNAME=root
|
||||||
|
# DB_PASSWORD=
|
||||||
|
|
||||||
|
SESSION_DRIVER=database
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
SESSION_ENCRYPT=false
|
||||||
|
SESSION_PATH=/
|
||||||
|
SESSION_DOMAIN=null
|
||||||
|
|
||||||
|
BROADCAST_CONNECTION=log
|
||||||
|
FILESYSTEM_DISK=local
|
||||||
|
QUEUE_CONNECTION=database
|
||||||
|
|
||||||
|
CACHE_STORE=database
|
||||||
|
CACHE_PREFIX=
|
||||||
|
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
|
REDIS_CLIENT=phpredis
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_MAILER=log
|
||||||
|
MAIL_HOST=127.0.0.1
|
||||||
|
MAIL_PORT=2525
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
# Core PHP Framework
|
||||||
|
CORE_CACHE_DISCOVERY=true
|
||||||
|
|
||||||
|
# CDN Configuration (optional)
|
||||||
|
CDN_ENABLED=false
|
||||||
|
CDN_DRIVER=bunny
|
||||||
|
BUNNYCDN_API_KEY=
|
||||||
|
BUNNYCDN_STORAGE_ZONE=
|
||||||
|
BUNNYCDN_PULL_ZONE=
|
||||||
|
|
||||||
|
# Flux Pro (optional)
|
||||||
|
FLUX_LICENSE_KEY=
|
||||||
12
.gemini/settings.json
Normal file
12
.gemini/settings.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://schema.gemini.google.dev/settings.json",
|
||||||
|
"codeAssist": {
|
||||||
|
"enabled": true,
|
||||||
|
"contextFiles": [
|
||||||
|
"GEMINI.md",
|
||||||
|
"CLAUDE.md",
|
||||||
|
"composer.json",
|
||||||
|
"config/core.php"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
*.blade.php diff=html
|
||||||
|
*.css diff=css
|
||||||
|
*.html diff=html
|
||||||
|
*.md diff=markdown
|
||||||
|
*.php diff=php
|
||||||
|
|
||||||
|
/.github export-ignore
|
||||||
|
CHANGELOG.md export-ignore
|
||||||
|
.styleci.yml export-ignore
|
||||||
4
.github/FUNDING.yml
vendored
Normal file
4
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# GitHub Sponsors configuration
|
||||||
|
# Support Trees for the Future through our fundraiser
|
||||||
|
|
||||||
|
custom: ["https://donate.trees.org/-/NPMMSVUP?member=SWZTDDWH"]
|
||||||
83
.github/copilot-instructions.md
vendored
Normal file
83
.github/copilot-instructions.md
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
# GitHub Copilot Instructions
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a Laravel application using the Core PHP Framework - a modular monolith architecture with event-driven module registration.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Module System
|
||||||
|
- Modules live in `app/Mod/{ModuleName}/`
|
||||||
|
- Each module has a `Boot.php` class with event listeners
|
||||||
|
- Events: `WebRoutesRegistering`, `ApiRoutesRegistering`, `AdminPanelBooting`
|
||||||
|
|
||||||
|
### Example Boot.php
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mod\Blog;
|
||||||
|
|
||||||
|
use Core\Events\WebRoutesRegistering;
|
||||||
|
use Core\Events\ApiRoutesRegistering;
|
||||||
|
|
||||||
|
class Boot
|
||||||
|
{
|
||||||
|
public static array $listens = [
|
||||||
|
WebRoutesRegistering::class => 'onWebRoutes',
|
||||||
|
ApiRoutesRegistering::class => 'onApiRoutes',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function onWebRoutes(WebRoutesRegistering $event): void
|
||||||
|
{
|
||||||
|
$event->routes(fn() => require __DIR__.'/Routes/web.php');
|
||||||
|
$event->views('blog', __DIR__.'/Views');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Coding Standards
|
||||||
|
|
||||||
|
### Language
|
||||||
|
- Use UK English (colour, organisation, centre, behaviour)
|
||||||
|
- No American spellings (color, organization, center, behavior)
|
||||||
|
|
||||||
|
### PHP Style
|
||||||
|
- PSR-12 with Laravel conventions
|
||||||
|
- Strict types: `declare(strict_types=1);`
|
||||||
|
- Type hints on all parameters and return types
|
||||||
|
- Final classes by default unless inheritance is intended
|
||||||
|
|
||||||
|
### Naming
|
||||||
|
- Models: singular PascalCase (`Post`, `Comment`)
|
||||||
|
- Tables: plural snake_case (`posts`, `comments`)
|
||||||
|
- Controllers: `{Model}Controller`
|
||||||
|
- Livewire: `{Feature}Page`, `{Feature}Modal`
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- Use Pest, not PHPUnit directly
|
||||||
|
- Feature tests for HTTP/Livewire
|
||||||
|
- Unit tests for services/utilities
|
||||||
|
|
||||||
|
## UI Framework
|
||||||
|
|
||||||
|
- **Livewire 3** for reactive components
|
||||||
|
- **Flux Pro** for UI components (not vanilla Alpine)
|
||||||
|
- **Tailwind CSS** for styling
|
||||||
|
- **Font Awesome Pro** for icons (not Heroicons)
|
||||||
|
|
||||||
|
## Key Packages
|
||||||
|
|
||||||
|
| Package | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `host-uk/core` | Core framework, events, modules |
|
||||||
|
| `host-uk/core-admin` | Admin panel, modals |
|
||||||
|
| `host-uk/core-api` | REST API, rate limiting |
|
||||||
|
| `host-uk/core-mcp` | AI agent tools (MCP) |
|
||||||
|
|
||||||
|
## Don't
|
||||||
|
|
||||||
|
- Don't use Heroicons (use Font Awesome Pro)
|
||||||
|
- Don't use vanilla Alpine components (use Flux Pro)
|
||||||
|
- Don't create controllers for Livewire pages
|
||||||
|
- Don't use American English spellings
|
||||||
|
- Don't add unnecessary abstractions
|
||||||
29
.github/dependabot.yml
vendored
Normal file
29
.github/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: composer
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
open-pull-requests-limit: 5
|
||||||
|
labels:
|
||||||
|
- dependencies
|
||||||
|
- php
|
||||||
|
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
open-pull-requests-limit: 5
|
||||||
|
labels:
|
||||||
|
- dependencies
|
||||||
|
- javascript
|
||||||
|
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: monthly
|
||||||
|
open-pull-requests-limit: 3
|
||||||
|
labels:
|
||||||
|
- dependencies
|
||||||
|
- ci
|
||||||
62
.github/package-workflows/README.md
vendored
Normal file
62
.github/package-workflows/README.md
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Package Workflows
|
||||||
|
|
||||||
|
These workflow templates are for **library packages** (host-uk/core, host-uk/core-api, etc.), not application projects.
|
||||||
|
|
||||||
|
## README Badges
|
||||||
|
|
||||||
|
Add these badges to your package README (replace `{package}` with your package name):
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[](https://github.com/host-uk/{package}/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/host-uk/{package})
|
||||||
|
[](https://packagist.org/packages/host-uk/{package})
|
||||||
|
[](https://packagist.org/packages/host-uk/{package})
|
||||||
|
[](LICENSE)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Copy the relevant workflows to your library's `.github/workflows/` directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In your library repo
|
||||||
|
mkdir -p .github/workflows
|
||||||
|
cp path/to/core-template/.github/package-workflows/ci.yml .github/workflows/
|
||||||
|
cp path/to/core-template/.github/package-workflows/release.yml .github/workflows/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflows
|
||||||
|
|
||||||
|
### ci.yml
|
||||||
|
- Runs on push/PR to main
|
||||||
|
- Tests against PHP 8.2, 8.3, 8.4
|
||||||
|
- Tests against Laravel 11 and 12
|
||||||
|
- Runs Pint linting
|
||||||
|
- Runs Pest tests
|
||||||
|
|
||||||
|
### release.yml
|
||||||
|
- Triggers on version tags (v*)
|
||||||
|
- Generates changelog using git-cliff
|
||||||
|
- Creates GitHub release
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
For these workflows to work, your package needs:
|
||||||
|
|
||||||
|
1. **cliff.toml** - Copy from core-template root
|
||||||
|
2. **Pest configured** - `composer require pestphp/pest --dev`
|
||||||
|
3. **Pint configured** - `composer require laravel/pint --dev`
|
||||||
|
4. **CODECOV_TOKEN** - Add to repo secrets for coverage uploads
|
||||||
|
5. **FUNDING.yml** - Copy `.github/FUNDING.yml` for sponsor button
|
||||||
|
|
||||||
|
## Recommended composer.json scripts
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"lint": "pint",
|
||||||
|
"test": "pest",
|
||||||
|
"test:coverage": "pest --coverage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
55
.github/package-workflows/ci.yml
vendored
Normal file
55
.github/package-workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
# CI workflow for library packages (host-uk/core-*, etc.)
|
||||||
|
# Copy this to .github/workflows/ci.yml in library repos
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
php: [8.2, 8.3, 8.4]
|
||||||
|
laravel: [11.*, 12.*]
|
||||||
|
exclude:
|
||||||
|
- php: 8.2
|
||||||
|
laravel: 12.*
|
||||||
|
|
||||||
|
name: PHP ${{ matrix.php }} / Laravel ${{ matrix.laravel }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite
|
||||||
|
coverage: pcov
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update
|
||||||
|
composer update --prefer-dist --no-interaction --no-progress
|
||||||
|
|
||||||
|
- name: Run Pint
|
||||||
|
run: vendor/bin/pint --test
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: vendor/bin/pest --ci --coverage --coverage-clover coverage.xml
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
if: matrix.php == '8.3' && matrix.laravel == '12.*'
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
with:
|
||||||
|
files: coverage.xml
|
||||||
|
fail_ci_if_error: false
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
40
.github/package-workflows/release.yml
vendored
Normal file
40
.github/package-workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Release workflow for library packages
|
||||||
|
# Copy this to .github/workflows/release.yml in library repos
|
||||||
|
|
||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Create Release
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: changelog
|
||||||
|
uses: orhun/git-cliff-action@v3
|
||||||
|
with:
|
||||||
|
config: cliff.toml
|
||||||
|
args: --latest --strip header
|
||||||
|
env:
|
||||||
|
OUTPUT: CHANGELOG.md
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
body_path: CHANGELOG.md
|
||||||
|
generate_release_notes: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
68
.github/workflows/ci.yml
vendored
Normal file
68
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
if: github.event.repository.visibility == 'public'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
php: [8.2, 8.3, 8.4]
|
||||||
|
|
||||||
|
name: PHP ${{ matrix.php }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite
|
||||||
|
coverage: pcov
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --prefer-dist --no-interaction --no-progress
|
||||||
|
|
||||||
|
- name: Run Pint
|
||||||
|
run: vendor/bin/pint --test
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: vendor/bin/pest --ci --coverage --coverage-clover coverage.xml
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
if: matrix.php == '8.3'
|
||||||
|
uses: codecov/codecov-action@v5
|
||||||
|
with:
|
||||||
|
files: coverage.xml
|
||||||
|
fail_ci_if_error: false
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
|
assets:
|
||||||
|
if: github.event.repository.visibility == 'public'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Assets
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build assets
|
||||||
|
run: npm run build
|
||||||
38
.github/workflows/release.yml
vendored
Normal file
38
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
if: github.event.repository.visibility == 'public'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Create Release
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: changelog
|
||||||
|
uses: orhun/git-cliff-action@v4
|
||||||
|
with:
|
||||||
|
config: cliff.toml
|
||||||
|
args: --latest --strip header
|
||||||
|
env:
|
||||||
|
OUTPUT: CHANGELOG.md
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
body_path: CHANGELOG.md
|
||||||
|
generate_release_notes: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
.DS_Store
|
||||||
|
/.phpunit.cache
|
||||||
|
/node_modules
|
||||||
|
/public/build
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/storage/*.key
|
||||||
|
/storage/pail
|
||||||
|
/vendor
|
||||||
|
.env
|
||||||
|
.env.backup
|
||||||
|
.env.production
|
||||||
|
.phpactor.json
|
||||||
|
.phpunit.result.cache
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
auth.json
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
/.fleet
|
||||||
|
/.idea
|
||||||
|
/.nova
|
||||||
|
/.vscode
|
||||||
|
/.zed
|
||||||
124
AGENTS.md
Normal file
124
AGENTS.md
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# AI Agent Instructions
|
||||||
|
|
||||||
|
> For Jules, Devin, and other autonomous coding agents.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. This is a Laravel 12 + Livewire 3 application
|
||||||
|
2. Modules go in `app/Mod/{Name}/Boot.php`
|
||||||
|
3. Use UK English (colour, not color)
|
||||||
|
4. Run `vendor/bin/pint --dirty` before committing
|
||||||
|
5. Run `vendor/bin/pest` to test
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
**Modular monolith** - Features are self-contained modules that register via events.
|
||||||
|
|
||||||
|
### Creating a Module
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan make:mod {Name} --all
|
||||||
|
```
|
||||||
|
|
||||||
|
Or manually create `app/Mod/{Name}/Boot.php`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Mod\{Name};
|
||||||
|
|
||||||
|
use Core\Events\WebRoutesRegistering;
|
||||||
|
|
||||||
|
class Boot
|
||||||
|
{
|
||||||
|
public static array $listens = [
|
||||||
|
WebRoutesRegistering::class => 'onWebRoutes',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function onWebRoutes(WebRoutesRegistering $event): void
|
||||||
|
{
|
||||||
|
$event->routes(fn() => require __DIR__.'/Routes/web.php');
|
||||||
|
$event->views('{name}', __DIR__.'/Views');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Task Checklist
|
||||||
|
|
||||||
|
When implementing features:
|
||||||
|
|
||||||
|
- [ ] Create module in `app/Mod/{Name}/`
|
||||||
|
- [ ] Add `Boot.php` with event listeners
|
||||||
|
- [ ] Create routes in `Routes/web.php` or `Routes/api.php`
|
||||||
|
- [ ] Create Livewire components in `Livewire/`
|
||||||
|
- [ ] Create Blade views in `Views/`
|
||||||
|
- [ ] Add migrations in `Migrations/`
|
||||||
|
- [ ] Write tests in `Tests/`
|
||||||
|
- [ ] Run `vendor/bin/pint --dirty`
|
||||||
|
- [ ] Run `vendor/bin/pest`
|
||||||
|
|
||||||
|
## File Locations
|
||||||
|
|
||||||
|
| What | Where |
|
||||||
|
|------|-------|
|
||||||
|
| Models | `app/Mod/{Name}/Models/` |
|
||||||
|
| Livewire | `app/Mod/{Name}/Livewire/` |
|
||||||
|
| Views | `app/Mod/{Name}/Views/` |
|
||||||
|
| Routes | `app/Mod/{Name}/Routes/` |
|
||||||
|
| Migrations | `app/Mod/{Name}/Migrations/` |
|
||||||
|
| Tests | `app/Mod/{Name}/Tests/` |
|
||||||
|
| Services | `app/Mod/{Name}/Services/` |
|
||||||
|
|
||||||
|
## Critical Rules
|
||||||
|
|
||||||
|
1. **UK English** - colour, organisation, centre (never American spellings)
|
||||||
|
2. **Strict types** - `declare(strict_types=1);` in every PHP file
|
||||||
|
3. **Type hints** - All parameters and return types
|
||||||
|
4. **Flux Pro** - Use Flux components, not vanilla Alpine
|
||||||
|
5. **Font Awesome** - Use FA icons, not Heroicons
|
||||||
|
6. **Pest** - Write tests using Pest syntax, not PHPUnit
|
||||||
|
|
||||||
|
## Example Livewire Component
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Mod\Blog\Livewire;
|
||||||
|
|
||||||
|
use App\Mod\Blog\Models\Post;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
class PostListPage extends Component
|
||||||
|
{
|
||||||
|
use WithPagination;
|
||||||
|
|
||||||
|
public function render(): View
|
||||||
|
{
|
||||||
|
return view('blog::posts.index', [
|
||||||
|
'posts' => Post::latest()->paginate(10),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Example
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Mod\Blog\Models\Post;
|
||||||
|
|
||||||
|
it('displays posts on the index page', function () {
|
||||||
|
$posts = Post::factory()->count(3)->create();
|
||||||
|
|
||||||
|
$this->get('/blog')
|
||||||
|
->assertOk()
|
||||||
|
->assertSee($posts->first()->title);
|
||||||
|
});
|
||||||
|
```
|
||||||
66
CLAUDE.md
Normal file
66
CLAUDE.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
# Core PHP Framework Project
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Modular monolith using Core PHP Framework. Modules live in `app/Mod/{Name}/Boot.php`.
|
||||||
|
|
||||||
|
**Event-driven registration:**
|
||||||
|
```php
|
||||||
|
class Boot
|
||||||
|
{
|
||||||
|
public static array $listens = [
|
||||||
|
WebRoutesRegistering::class => 'onWebRoutes',
|
||||||
|
ApiRoutesRegistering::class => 'onApiRoutes',
|
||||||
|
AdminPanelBooting::class => 'onAdminPanel',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer run dev # Dev server (if configured)
|
||||||
|
php artisan serve # Laravel dev server
|
||||||
|
npm run dev # Vite
|
||||||
|
./vendor/bin/pint --dirty # Format changed files
|
||||||
|
php artisan test # All tests
|
||||||
|
php artisan make:mod Blog # Create module
|
||||||
|
```
|
||||||
|
|
||||||
|
## Module Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
app/Mod/Blog/
|
||||||
|
├── Boot.php # Event listeners
|
||||||
|
├── Models/ # Eloquent models
|
||||||
|
├── Routes/
|
||||||
|
│ ├── web.php # Web routes
|
||||||
|
│ └── api.php # API routes
|
||||||
|
├── Views/ # Blade templates
|
||||||
|
├── Livewire/ # Livewire components
|
||||||
|
├── Migrations/ # Database migrations
|
||||||
|
└── Tests/ # Module tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Packages
|
||||||
|
|
||||||
|
| Package | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `host-uk/core` | Core framework, events, module discovery |
|
||||||
|
| `host-uk/core-admin` | Admin panel, Livewire modals |
|
||||||
|
| `host-uk/core-api` | REST API, scopes, rate limiting, webhooks |
|
||||||
|
| `host-uk/core-mcp` | Model Context Protocol for AI agents |
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- UK English (colour, organisation, centre)
|
||||||
|
- PSR-12 coding style (Laravel Pint)
|
||||||
|
- Pest for testing
|
||||||
|
- Livewire + Flux Pro for UI
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
- `Core\` namespace and vendor packages: EUPL-1.2 (copyleft)
|
||||||
|
- `app/Mod/*`, `app/Website/*`: Your choice (no copyleft)
|
||||||
|
|
||||||
|
See LICENSE for full details.
|
||||||
122
GEMINI.md
Normal file
122
GEMINI.md
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
# Core PHP Framework - AI Assistant Context
|
||||||
|
|
||||||
|
> For Gemini Code Assist, Jules, and other Google AI tools.
|
||||||
|
|
||||||
|
## Project Type
|
||||||
|
|
||||||
|
Laravel 12 application using Core PHP Framework - a modular monolith with event-driven architecture.
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── Mod/ # Feature modules (your code)
|
||||||
|
│ └── {Name}/
|
||||||
|
│ ├── Boot.php # Event listeners
|
||||||
|
│ ├── Models/
|
||||||
|
│ ├── Routes/
|
||||||
|
│ ├── Views/
|
||||||
|
│ └── Livewire/
|
||||||
|
├── Core/ # Local framework overrides (EUPL-1.2)
|
||||||
|
└── Providers/
|
||||||
|
|
||||||
|
config/core.php # Framework configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Module Pattern
|
||||||
|
|
||||||
|
Every module has a `Boot.php` with static `$listens` array:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Mod\Shop;
|
||||||
|
|
||||||
|
use Core\Events\WebRoutesRegistering;
|
||||||
|
use Core\Events\ApiRoutesRegistering;
|
||||||
|
use Core\Events\AdminPanelBooting;
|
||||||
|
|
||||||
|
class Boot
|
||||||
|
{
|
||||||
|
public static array $listens = [
|
||||||
|
WebRoutesRegistering::class => 'onWebRoutes',
|
||||||
|
ApiRoutesRegistering::class => 'onApiRoutes',
|
||||||
|
AdminPanelBooting::class => 'onAdminPanel',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function onWebRoutes(WebRoutesRegistering $event): void
|
||||||
|
{
|
||||||
|
$event->routes(fn() => require __DIR__.'/Routes/web.php');
|
||||||
|
$event->views('shop', __DIR__.'/Views');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onApiRoutes(ApiRoutesRegistering $event): void
|
||||||
|
{
|
||||||
|
$event->routes(fn() => require __DIR__.'/Routes/api.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAdminPanel(AdminPanelBooting $event): void
|
||||||
|
{
|
||||||
|
$event->navigation('Shop', 'shop.admin.index', 'shopping-cart');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style Requirements
|
||||||
|
|
||||||
|
### Language: UK English
|
||||||
|
- colour (not color)
|
||||||
|
- organisation (not organization)
|
||||||
|
- centre (not center)
|
||||||
|
- behaviour (not behavior)
|
||||||
|
- licence (noun), license (verb)
|
||||||
|
|
||||||
|
### PHP Standards
|
||||||
|
- `declare(strict_types=1);` in all files
|
||||||
|
- Full type hints (parameters + return types)
|
||||||
|
- PSR-12 formatting (use Laravel Pint)
|
||||||
|
- Pest for testing
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
| Type | Convention | Example |
|
||||||
|
|------|------------|---------|
|
||||||
|
| Model | Singular PascalCase | `Product` |
|
||||||
|
| Table | Plural snake_case | `products` |
|
||||||
|
| Controller | `{Model}Controller` | `ProductController` |
|
||||||
|
| Livewire Page | `{Feature}Page` | `ProductListPage` |
|
||||||
|
| Livewire Modal | `{Feature}Modal` | `EditProductModal` |
|
||||||
|
|
||||||
|
## UI Stack
|
||||||
|
|
||||||
|
- **Livewire 3** - Server-side reactivity
|
||||||
|
- **Flux Pro** - UI component library (NOT vanilla Alpine)
|
||||||
|
- **Tailwind CSS** - Utility-first styling
|
||||||
|
- **Font Awesome Pro** - Icons (NOT Heroicons)
|
||||||
|
|
||||||
|
## Common Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan make:mod Blog --all # Create module with all features
|
||||||
|
php artisan serve # Development server
|
||||||
|
vendor/bin/pint --dirty # Format changed files
|
||||||
|
vendor/bin/pest # Run tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Packages
|
||||||
|
|
||||||
|
| Package | Namespace | Purpose |
|
||||||
|
|---------|-----------|---------|
|
||||||
|
| host-uk/core | `Core\` | Framework core |
|
||||||
|
| host-uk/core-admin | `Core\Admin\` | Admin panel |
|
||||||
|
| host-uk/core-api | `Core\Api\` | REST API |
|
||||||
|
| host-uk/core-mcp | `Core\Mcp\` | AI agent tools |
|
||||||
|
|
||||||
|
## Avoid
|
||||||
|
|
||||||
|
- American English spellings
|
||||||
|
- Heroicons (use Font Awesome)
|
||||||
|
- Vanilla Alpine components (use Flux)
|
||||||
|
- Over-engineering / premature abstraction
|
||||||
|
- PHPUnit syntax (use Pest)
|
||||||
108
LICENSE
Normal file
108
LICENSE
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
Core PHP Framework Template
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Copyright (c) 2026 Host UK / Snider
|
||||||
|
|
||||||
|
This project uses a dual-licensing approach:
|
||||||
|
|
||||||
|
|
||||||
|
1. CORE FRAMEWORK CODE (EUPL-1.2)
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
The Core PHP Framework packages (host-uk/core, host-uk/core-admin,
|
||||||
|
host-uk/core-api, host-uk/core-mcp) and any code within the `Core\`
|
||||||
|
namespace are licensed under the European Union Public Licence v1.2
|
||||||
|
(EUPL-1.2).
|
||||||
|
|
||||||
|
The full EUPL-1.2 license text is available at:
|
||||||
|
https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
|
||||||
|
|
||||||
|
And in the Core PHP Framework repository:
|
||||||
|
https://github.com/host-uk/core-php/blob/main/LICENSE
|
||||||
|
|
||||||
|
|
||||||
|
2. APPLICATION CODE EXCEPTION
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
As the copyright holder, we grant the following additional permission:
|
||||||
|
|
||||||
|
Code you create within the following directories is EXEMPT from the
|
||||||
|
EUPL-1.2 copyleft requirements and may be licensed under any terms
|
||||||
|
you choose (including proprietary licenses):
|
||||||
|
|
||||||
|
app/Mod/ - Your feature modules
|
||||||
|
app/Website/ - Your website/domain modules
|
||||||
|
app/Service/ - Your service classes
|
||||||
|
database/ - Your migrations, seeders, factories
|
||||||
|
resources/ - Your views, assets, translations
|
||||||
|
routes/ - Your route definitions
|
||||||
|
tests/ - Your test files
|
||||||
|
config/ - Your configuration files (except config/core.php)
|
||||||
|
|
||||||
|
This exception applies ONLY to original code you create in these
|
||||||
|
directories. It does NOT apply to:
|
||||||
|
|
||||||
|
- Modified copies of Core framework code
|
||||||
|
- Code that extends or overrides the `Core\` namespace
|
||||||
|
- Derivative works of the Core framework itself
|
||||||
|
|
||||||
|
|
||||||
|
3. CORE NAMESPACE MODIFICATIONS
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
If you create local overrides or extensions within the `Core\` namespace
|
||||||
|
(e.g., in `app/Core/`), those modifications ARE subject to EUPL-1.2 and
|
||||||
|
its copyleft requirements.
|
||||||
|
|
||||||
|
We encourage you to submit such modifications as pull requests to:
|
||||||
|
https://github.com/host-uk/core-php
|
||||||
|
|
||||||
|
This requirement constitutes the consideration for the license grant
|
||||||
|
herein. The Core PHP Framework is not provided without cost; rather,
|
||||||
|
the license fee is paid in kind through the contribution of improvements
|
||||||
|
to the community. By using this software, you acknowledge and agree that
|
||||||
|
modifications to the Core\ namespace shall be made available to the
|
||||||
|
community under the same terms, ensuring that all users benefit from
|
||||||
|
collective improvements. This reciprocal obligation is a fundamental
|
||||||
|
condition of the license grant and not merely a request.
|
||||||
|
|
||||||
|
|
||||||
|
4. SUMMARY
|
||||||
|
----------
|
||||||
|
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Location │ License │ Copyleft Required? │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ vendor/host-uk/* │ EUPL-1.2 │ Yes │
|
||||||
|
│ app/Core/* │ EUPL-1.2 │ Yes (submit as PR) │
|
||||||
|
│ Core\ namespace │ EUPL-1.2 │ Yes │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ app/Mod/* │ Your choice │ No │
|
||||||
|
│ app/Website/* │ Your choice │ No │
|
||||||
|
│ app/Service/* │ Your choice │ No │
|
||||||
|
│ database/* │ Your choice │ No │
|
||||||
|
│ resources/* │ Your choice │ No │
|
||||||
|
│ routes/* │ Your choice │ No │
|
||||||
|
│ tests/* │ Your choice │ No │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
|
||||||
|
5. WARRANTY DISCLAIMER
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
6. QUESTIONS
|
||||||
|
------------
|
||||||
|
|
||||||
|
If you have questions about licensing, contact: hello@host.uk.com
|
||||||
|
|
||||||
|
For the full EUPL-1.2 text, see:
|
||||||
|
https://github.com/host-uk/core-php/blob/main/LICENSE
|
||||||
138
README.md
Normal file
138
README.md
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
# Core PHP Framework Project
|
||||||
|
|
||||||
|
[](https://github.com/host-uk/core-template/actions/workflows/ci.yml)
|
||||||
|
[](https://codecov.io/gh/host-uk/core-template)
|
||||||
|
[](https://packagist.org/packages/host-uk/core-template)
|
||||||
|
[](https://laravel.com)
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
A modular monolith Laravel application built with Core PHP Framework.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Core Framework** - Event-driven module system with lazy loading
|
||||||
|
- **Admin Panel** - Livewire-powered admin interface with Flux UI
|
||||||
|
- **REST API** - Scoped API keys, rate limiting, webhooks, OpenAPI docs
|
||||||
|
- **MCP Tools** - Model Context Protocol for AI agent integration
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- PHP 8.2+
|
||||||
|
- Composer 2.x
|
||||||
|
- SQLite (default) or MySQL/PostgreSQL
|
||||||
|
- Node.js 18+ (for frontend assets)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone or create from template
|
||||||
|
git clone https://github.com/host-uk/core-template.git my-project
|
||||||
|
cd my-project
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
composer install
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Configure environment
|
||||||
|
cp .env.example .env
|
||||||
|
php artisan key:generate
|
||||||
|
|
||||||
|
# Set up database
|
||||||
|
touch database/database.sqlite
|
||||||
|
php artisan migrate
|
||||||
|
|
||||||
|
# Start development server
|
||||||
|
php artisan serve
|
||||||
|
```
|
||||||
|
|
||||||
|
Visit: http://localhost:8000
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── Console/ # Artisan commands
|
||||||
|
├── Http/ # Controllers & Middleware
|
||||||
|
├── Models/ # Eloquent models
|
||||||
|
├── Mod/ # Your custom modules
|
||||||
|
└── Providers/ # Service providers
|
||||||
|
|
||||||
|
config/
|
||||||
|
└── core.php # Core framework configuration
|
||||||
|
|
||||||
|
routes/
|
||||||
|
├── web.php # Public web routes
|
||||||
|
├── api.php # REST API routes
|
||||||
|
└── console.php # Artisan commands
|
||||||
|
```
|
||||||
|
|
||||||
|
## Creating Modules
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a new module with all features
|
||||||
|
php artisan make:mod Blog --all
|
||||||
|
|
||||||
|
# Create module with specific features
|
||||||
|
php artisan make:mod Shop --web --api --admin
|
||||||
|
```
|
||||||
|
|
||||||
|
Modules follow the event-driven pattern:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mod\Blog;
|
||||||
|
|
||||||
|
use Core\Events\WebRoutesRegistering;
|
||||||
|
use Core\Events\ApiRoutesRegistering;
|
||||||
|
use Core\Events\AdminPanelBooting;
|
||||||
|
|
||||||
|
class Boot
|
||||||
|
{
|
||||||
|
public static array $listens = [
|
||||||
|
WebRoutesRegistering::class => 'onWebRoutes',
|
||||||
|
ApiRoutesRegistering::class => 'onApiRoutes',
|
||||||
|
AdminPanelBooting::class => 'onAdminPanel',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function onWebRoutes(WebRoutesRegistering $event): void
|
||||||
|
{
|
||||||
|
$event->routes(fn() => require __DIR__.'/Routes/web.php');
|
||||||
|
$event->views('blog', __DIR__.'/Views');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Packages
|
||||||
|
|
||||||
|
| Package | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `host-uk/core` | Core framework components |
|
||||||
|
| `host-uk/core-admin` | Admin panel & Livewire modals |
|
||||||
|
| `host-uk/core-api` | REST API with scopes & webhooks |
|
||||||
|
| `host-uk/core-mcp` | Model Context Protocol tools |
|
||||||
|
|
||||||
|
## Flux Pro (Optional)
|
||||||
|
|
||||||
|
This template uses the free Flux UI components. If you have a Flux Pro license:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configure authentication
|
||||||
|
composer config http-basic.composer.fluxui.dev your-email your-license-key
|
||||||
|
|
||||||
|
# Add the repository
|
||||||
|
composer config repositories.flux-pro composer https://composer.fluxui.dev
|
||||||
|
|
||||||
|
# Install Flux Pro
|
||||||
|
composer require livewire/flux-pro
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [Core PHP Framework](https://github.com/host-uk/core-php)
|
||||||
|
- [Getting Started Guide](https://host-uk.github.io/core-php/guide/)
|
||||||
|
- [Architecture](https://host-uk.github.io/core-php/architecture/)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
EUPL-1.2 (European Union Public Licence)
|
||||||
0
app/Http/Controllers/.gitkeep
Normal file
0
app/Http/Controllers/.gitkeep
Normal file
0
app/Mod/.gitkeep
Normal file
0
app/Mod/.gitkeep
Normal file
0
app/Models/.gitkeep
Normal file
0
app/Models/.gitkeep
Normal file
24
app/Providers/AppServiceProvider.php
Normal file
24
app/Providers/AppServiceProvider.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class AppServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*/
|
||||||
|
public function boot(): void
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
15
artisan
Executable file
15
artisan
Executable file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Input\ArgvInput;
|
||||||
|
|
||||||
|
define('LARAVEL_START', microtime(true));
|
||||||
|
|
||||||
|
// Register the Composer autoloader...
|
||||||
|
require __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
|
// Bootstrap Laravel and handle the command...
|
||||||
|
$status = (require_once __DIR__.'/bootstrap/app.php')
|
||||||
|
->handleCommand(new ArgvInput);
|
||||||
|
|
||||||
|
exit($status);
|
||||||
26
bootstrap/app.php
Normal file
26
bootstrap/app.php
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
|
use Illuminate\Foundation\Configuration\Exceptions;
|
||||||
|
use Illuminate\Foundation\Configuration\Middleware;
|
||||||
|
|
||||||
|
return Application::configure(basePath: dirname(__DIR__))
|
||||||
|
->withProviders([
|
||||||
|
// Core PHP Framework
|
||||||
|
\Core\LifecycleEventProvider::class,
|
||||||
|
\Core\Website\Boot::class,
|
||||||
|
\Core\Front\Boot::class,
|
||||||
|
\Core\Mod\Boot::class,
|
||||||
|
])
|
||||||
|
->withRouting(
|
||||||
|
web: __DIR__.'/../routes/web.php',
|
||||||
|
api: __DIR__.'/../routes/api.php',
|
||||||
|
commands: __DIR__.'/../routes/console.php',
|
||||||
|
health: '/up',
|
||||||
|
)
|
||||||
|
->withMiddleware(function (Middleware $middleware) {
|
||||||
|
\Core\Front\Boot::middleware($middleware);
|
||||||
|
})
|
||||||
|
->withExceptions(function (Exceptions $exceptions) {
|
||||||
|
//
|
||||||
|
})->create();
|
||||||
2
bootstrap/cache/.gitignore
vendored
Normal file
2
bootstrap/cache/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
5
bootstrap/providers.php
Normal file
5
bootstrap/providers.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
App\Providers\AppServiceProvider::class,
|
||||||
|
];
|
||||||
48
cliff.toml
Normal file
48
cliff.toml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# git-cliff configuration
|
||||||
|
# https://git-cliff.org
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
header = """
|
||||||
|
# Changelog\n
|
||||||
|
All notable changes to this project will be documented in this file.\n
|
||||||
|
"""
|
||||||
|
body = """
|
||||||
|
{% if version %}\
|
||||||
|
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||||
|
{% else %}\
|
||||||
|
## [Unreleased]
|
||||||
|
{% endif %}\
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}
|
||||||
|
### {{ group | striptags | trim | upper_first }}
|
||||||
|
{% for commit in commits %}
|
||||||
|
- {% if commit.scope %}**{{ commit.scope }}:** {% endif %}\
|
||||||
|
{{ commit.message | upper_first }}\
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}\n
|
||||||
|
"""
|
||||||
|
footer = """
|
||||||
|
<!-- generated by git-cliff -->
|
||||||
|
"""
|
||||||
|
trim = true
|
||||||
|
|
||||||
|
[git]
|
||||||
|
conventional_commits = true
|
||||||
|
filter_unconventional = true
|
||||||
|
split_commits = false
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "Features" },
|
||||||
|
{ message = "^fix", group = "Bug Fixes" },
|
||||||
|
{ message = "^doc", group = "Documentation" },
|
||||||
|
{ message = "^perf", group = "Performance" },
|
||||||
|
{ message = "^refactor", group = "Refactor" },
|
||||||
|
{ message = "^style", group = "Styling" },
|
||||||
|
{ message = "^test", group = "Testing" },
|
||||||
|
{ message = "^chore\\(release\\)", skip = true },
|
||||||
|
{ message = "^chore\\(deps.*\\)", skip = true },
|
||||||
|
{ message = "^chore|^ci", group = "Miscellaneous" },
|
||||||
|
{ body = ".*security", group = "Security" },
|
||||||
|
]
|
||||||
|
protect_breaking_commits = false
|
||||||
|
filter_commits = false
|
||||||
|
topo_order = false
|
||||||
|
sort_commits = "oldest"
|
||||||
78
composer.json
Normal file
78
composer.json
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
"name": "host-uk/core-template",
|
||||||
|
"type": "project",
|
||||||
|
"description": "Core PHP Framework - Project Template",
|
||||||
|
"keywords": ["laravel", "core-php", "modular", "framework", "template"],
|
||||||
|
"license": "EUPL-1.2",
|
||||||
|
"require": {
|
||||||
|
"php": "^8.2",
|
||||||
|
"laravel/framework": "^12.0",
|
||||||
|
"laravel/tinker": "^2.10",
|
||||||
|
"livewire/flux": "^2.0",
|
||||||
|
"livewire/livewire": "^3.0",
|
||||||
|
"host-uk/core": "dev-main",
|
||||||
|
"host-uk/core-admin": "dev-main",
|
||||||
|
"host-uk/core-api": "dev-main",
|
||||||
|
"host-uk/core-mcp": "dev-main"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"fakerphp/faker": "^1.23",
|
||||||
|
"laravel/pail": "^1.2",
|
||||||
|
"laravel/pint": "^1.18",
|
||||||
|
"laravel/sail": "^1.41",
|
||||||
|
"mockery/mockery": "^1.6",
|
||||||
|
"nunomaduro/collision": "^8.6",
|
||||||
|
"pestphp/pest": "^3.0",
|
||||||
|
"pestphp/pest-plugin-laravel": "^3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "app/",
|
||||||
|
"Database\\Factories\\": "database/factories/",
|
||||||
|
"Database\\Seeders\\": "database/seeders/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://github.com/host-uk/core-php.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||||
|
"@php artisan package:discover --ansi"
|
||||||
|
],
|
||||||
|
"post-update-cmd": [
|
||||||
|
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||||
|
],
|
||||||
|
"post-root-package-install": [
|
||||||
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||||
|
],
|
||||||
|
"post-create-project-cmd": [
|
||||||
|
"@php artisan key:generate --ansi",
|
||||||
|
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
|
||||||
|
"@php artisan migrate --graceful --ansi"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"dont-discover": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
|
"preferred-install": "dist",
|
||||||
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"php-http/discovery": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
||||||
24
config/core.php
Normal file
24
config/core.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Core PHP Framework Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
'module_paths' => [
|
||||||
|
app_path('Core'),
|
||||||
|
app_path('Mod'),
|
||||||
|
app_path('Website'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'services' => [
|
||||||
|
'cache_discovery' => env('CORE_CACHE_DISCOVERY', true),
|
||||||
|
],
|
||||||
|
|
||||||
|
'cdn' => [
|
||||||
|
'enabled' => env('CDN_ENABLED', false),
|
||||||
|
'driver' => env('CDN_DRIVER', 'bunny'),
|
||||||
|
],
|
||||||
|
];
|
||||||
0
database/factories/.gitkeep
Normal file
0
database/factories/.gitkeep
Normal file
0
database/migrations/.gitkeep
Normal file
0
database/migrations/.gitkeep
Normal file
16
database/seeders/DatabaseSeeder.php
Normal file
16
database/seeders/DatabaseSeeder.php
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class DatabaseSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Seed the application's database.
|
||||||
|
*/
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
// Core modules handle their own seeding
|
||||||
|
}
|
||||||
|
}
|
||||||
16
package.json
Normal file
16
package.json
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
|
"axios": "^1.7.4",
|
||||||
|
"laravel-vite-plugin": "^2.1.0",
|
||||||
|
"postcss": "^8.4.47",
|
||||||
|
"tailwindcss": "^4.1.18",
|
||||||
|
"vite": "^7.3.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
33
phpunit.xml
Normal file
33
phpunit.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Unit">
|
||||||
|
<directory>tests/Unit</directory>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite name="Feature">
|
||||||
|
<directory>tests/Feature</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<source>
|
||||||
|
<include>
|
||||||
|
<directory>app</directory>
|
||||||
|
</include>
|
||||||
|
</source>
|
||||||
|
<php>
|
||||||
|
<env name="APP_ENV" value="testing"/>
|
||||||
|
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
||||||
|
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||||
|
<env name="CACHE_STORE" value="array"/>
|
||||||
|
<env name="DB_CONNECTION" value="sqlite"/>
|
||||||
|
<env name="DB_DATABASE" value=":memory:"/>
|
||||||
|
<env name="MAIL_MAILER" value="array"/>
|
||||||
|
<env name="PULSE_ENABLED" value="false"/>
|
||||||
|
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||||
|
<env name="SESSION_DRIVER" value="array"/>
|
||||||
|
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
||||||
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
21
public/.htaccess
Normal file
21
public/.htaccess
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
<IfModule mod_negotiation.c>
|
||||||
|
Options -MultiViews -Indexes
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
RewriteEngine On
|
||||||
|
|
||||||
|
# Handle Authorization Header
|
||||||
|
RewriteCond %{HTTP:Authorization} .
|
||||||
|
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||||
|
|
||||||
|
# Redirect Trailing Slashes If Not A Folder...
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_URI} (.+)/$
|
||||||
|
RewriteRule ^ %1 [L,R=301]
|
||||||
|
|
||||||
|
# Send Requests To Front Controller...
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteRule ^ index.php [L]
|
||||||
|
</IfModule>
|
||||||
17
public/index.php
Normal file
17
public/index.php
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
define('LARAVEL_START', microtime(true));
|
||||||
|
|
||||||
|
// Determine if the application is in maintenance mode...
|
||||||
|
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||||
|
require $maintenance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the Composer autoloader...
|
||||||
|
require __DIR__.'/../vendor/autoload.php';
|
||||||
|
|
||||||
|
// Bootstrap Laravel and handle the request...
|
||||||
|
(require_once __DIR__.'/../bootstrap/app.php')
|
||||||
|
->handleRequest(Request::capture());
|
||||||
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
3
resources/css/app.css
Normal file
3
resources/css/app.css
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
1
resources/js/app.js
Normal file
1
resources/js/app.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
import './bootstrap';
|
||||||
3
resources/js/bootstrap.js
vendored
Normal file
3
resources/js/bootstrap.js
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
window.axios = axios;
|
||||||
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||||
65
resources/views/welcome.blade.php
Normal file
65
resources/views/welcome.blade.php
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Core PHP Framework</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
.version {
|
||||||
|
color: #888;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: 1px solid #667eea;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
background: #667eea;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Core PHP Framework</h1>
|
||||||
|
<p class="version">Laravel {{ Illuminate\Foundation\Application::VERSION }} | PHP {{ PHP_VERSION }}</p>
|
||||||
|
<div class="links">
|
||||||
|
<a href="https://github.com/host-uk/core-php">Documentation</a>
|
||||||
|
<a href="/admin">Admin Panel</a>
|
||||||
|
<a href="/api/docs">API Docs</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
routes/api.php
Normal file
5
routes/api.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
// API routes are registered via Core modules
|
||||||
3
routes/console.php
Normal file
3
routes/console.php
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// Console commands are registered via Core modules
|
||||||
7
routes/web.php
Normal file
7
routes/web.php
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
Route::get('/', function () {
|
||||||
|
return view('welcome');
|
||||||
|
});
|
||||||
3
storage/app/.gitignore
vendored
Normal file
3
storage/app/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
*
|
||||||
|
!public/
|
||||||
|
!.gitignore
|
||||||
2
storage/app/public/.gitignore
vendored
Normal file
2
storage/app/public/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
9
storage/framework/.gitignore
vendored
Normal file
9
storage/framework/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
compiled.php
|
||||||
|
config.php
|
||||||
|
down
|
||||||
|
events.scanned.php
|
||||||
|
maintenance.php
|
||||||
|
routes.php
|
||||||
|
routes.scanned.php
|
||||||
|
schedule-*
|
||||||
|
services.json
|
||||||
3
storage/framework/cache/.gitignore
vendored
Normal file
3
storage/framework/cache/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
*
|
||||||
|
!data/
|
||||||
|
!.gitignore
|
||||||
2
storage/framework/cache/data/.gitignore
vendored
Normal file
2
storage/framework/cache/data/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
2
storage/framework/sessions/.gitignore
vendored
Normal file
2
storage/framework/sessions/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
2
storage/framework/testing/.gitignore
vendored
Normal file
2
storage/framework/testing/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
2
storage/framework/views/.gitignore
vendored
Normal file
2
storage/framework/views/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
2
storage/logs/.gitignore
vendored
Normal file
2
storage/logs/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
11
tailwind.config.js
Normal file
11
tailwind.config.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: [
|
||||||
|
"./resources/**/*.blade.php",
|
||||||
|
"./resources/**/*.js",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
0
tests/Feature/.gitkeep
Normal file
0
tests/Feature/.gitkeep
Normal file
10
tests/TestCase.php
Normal file
10
tests/TestCase.php
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||||
|
|
||||||
|
abstract class TestCase extends BaseTestCase
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
0
tests/Unit/.gitkeep
Normal file
0
tests/Unit/.gitkeep
Normal file
11
vite.config.js
Normal file
11
vite.config.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import laravel from 'laravel-vite-plugin';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
laravel({
|
||||||
|
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||||
|
refresh: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue