Skip to content

Commit 4dda2bd

Browse files
committed
chore: genesis baseline for reviewable dev history
Flatten opaque incremental dev history into a single canonical baseline. Establish package boundaries, shared test bootstrap, and documentation scaffolding fit for external review.
0 parents  commit 4dda2bd

22 files changed

Lines changed: 4076 additions & 0 deletions

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
APP_ENV=dev
2+
APP_DEBUG=true
3+
APP_TIMEZONE=Asia/Shanghai
4+
MASTER_KEYMASTER_KEY=
5+
SERVER_HOST=localhost
6+
SERVER_TYPE=php
7+
SERVER_PORT=9501
8+
LOG_LEVEL=debug

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.gitattributes export-ignore
2+
.gitignore export-ignore
3+
/tests export-ignore
4+
/.github export-ignore

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
concurrency:
10+
group: ci-${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
package:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout source
18+
uses: actions/checkout@v5
19+
20+
- name: Setup PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: '8.3'
24+
coverage: none
25+
26+
- name: Install package dependencies
27+
run: composer install --no-interaction --prefer-dist
28+
29+
- name: Validate composer metadata
30+
run: composer validate --no-check-lock --no-plugins
31+
32+
- name: Run fast package tests
33+
run: composer run test:unit

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/runtime
2+
/.env
3+
/vendor
4+
/.idea
5+
/tests/.phpstan.cache
6+
/tests/.phpunit.cache
7+
/tests/coverage

.phpstorm.meta.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
// IDE metadata template for Switon application skeletons.
3+
// Keep this file limited to stable, skeleton-default application surfaces.
4+
5+
namespace PHPSTORM_META {
6+
exitPoint(\abort());
7+
8+
override(\Switon\Core\App::get(), map(['' => '@']));
9+
override(\Psr\Container\ContainerInterface::get(), map(['' => '@']));
10+
override(\make(), map(['' => '@']));
11+
12+
expectedArguments(\Switon\Http\RequestInterface::server(), 0, array_keys($_SERVER)[$i]);
13+
14+
expectedArguments(
15+
\Switon\Http\ResponseInterface::json(), 0, ['code' => 0, 'msg' => '', 'data' => []]
16+
);
17+
18+
registerArgumentsSet(
19+
'validator_constraint_type', ['bool', 'bit', 'int', 'float', 'array', 'mixed', 'iterable', 'mixed']
20+
);
21+
expectedArguments(
22+
\Switon\Validating\Attribute\Type::__construct(), 0, argumentsSet('validator_constraint_type')
23+
);
24+
25+
expectedArguments(
26+
\Switon\Core\Json::stringify(), 1,
27+
JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT
28+
| JSON_FORCE_OBJECT | JSON_PRESERVE_ZERO_FRACTION | JSON_PARTIAL_OUTPUT_ON_ERROR
29+
| JSON_UNESCAPED_LINE_TERMINATORS
30+
);
31+
32+
registerArgumentsSet('request_header', [
33+
'accept-charset',
34+
'accept-encoding',
35+
'accept-language',
36+
'authorization',
37+
'cache-control',
38+
'connection',
39+
'content-length',
40+
'cookie',
41+
'host',
42+
'origin',
43+
'referer',
44+
'set-cookie',
45+
'transfer-encoding',
46+
'user-agent',
47+
'if-none-match',
48+
'x-real-ip',
49+
'x-forwarded-for',
50+
'x-requested-with',
51+
]);
52+
expectedArguments(\Switon\Http\RequestInterface::header(), 0, argumentsSet('request_header'));
53+
}

AGENTS.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Switon App Rules
2+
3+
**TL;DR** — Setup: `create-project` creates `.env` and generates `MASTER_KEY`. CLI: `bash bin/console` (fallback: `php switon.php` on Windows when shell wrapper execution is unavailable). Dev HTTP: `php public/index.php` (`.env` sets `SERVER_TYPE=php`).
4+
5+
**Framework:** Switon (PHP). **Scope:** `vendor/switon/*`.
6+
7+
---
8+
9+
## Core Rules
10+
11+
- Do not invent class names, interfaces, config keys, or commands. Verify machine-meaningful identifiers against the codebase or discovery commands.
12+
- Use `router:list --json` instead of a hand-written route list.
13+
- `vendor/switon/*` is read-only.
14+
- Do not run `composer require`, delete files, or make broad refactors without asking.
15+
- Do not commit or log `.env` or `--uri` output.
16+
17+
---
18+
19+
## Project Structure
20+
21+
| Path | Purpose |
22+
|------|---------|
23+
| `app/` | Application code (controllers, commands, entities, repositories, services, listeners). |
24+
| `switon.yml` | Main application config file. |
25+
| `config/` | Optional PHP-only configuration patches. |
26+
| `public/index.php` | HTTP entry. |
27+
| `switon.php` | CLI entry. |
28+
| `docs/` | Project docs. |
29+
| `skills/` | App skills only; use `app-` for project skills and `switon-` for built-in Switon app-facing skills. |
30+
| `vendor/switon/*` | Framework; read-only. |
31+
32+
Routes: configure the prefix in `switon.yml`; actions live in `app/Controller/`.
33+
34+
---
35+
36+
## CLI
37+
38+
- Entrypoint: `bash bin/console` (fallback: `php switon.php` on Windows when shell wrapper execution is unavailable).
39+
- Options: `--name=value` or `--flag`.
40+
- Tool discovery: `tool:list` for the command list; `tool:description <invocation>` for one command.
41+
- For tool-only tasks, `tool:list` and `tool:description` are enough.
42+
- Prefer `class:*` and `event:*` tools to read framework code and events by FQCN instead of raw file reads.
43+
- Common tools: `router:resolve <path> [verb] --json`, `router:list [filter] --json`, `class:list [filter]`, `class:inspect <FQCN>`, `class:content <FQCN>` or `class:content <FQCN>::<method>`, `event:classes [filter] --json`, `event:class <FQCN> --json`, `event:category <class> --json`, `event:by-code <code> --json`.
44+
45+
---
46+
47+
## Runtime
48+
49+
- Run: `php public/index.php`.
50+
- Sample routes: `/`, `/time/current` (see `router:list --json`).
51+
52+
---
53+
54+
## Switon package rules
55+
56+
- Auto-registration: default bindings lowest; explicit overrides.
57+
- Config: prefer root `switon.yml`; use `config/*.php` only for PHP-only values or pre-built instances.
58+
- Events: use the component `Event/` namespace and FQCNs.
59+
- Exceptions: use `Switon\Core\Exception\*`, not PHP built-ins.
60+
- Runtime: package `composer.json` (including `ext-*`) is source of truth.
61+
62+
---
63+
64+
## Sword Templates
65+
66+
- Prefer `@inject('name', FQCN::class)` for small template-level service access.
67+
- Do not inline `\Switon\Core\App::get(...)` when `@inject` can express the dependency.
68+
- Prefer upstream view vars for business data; use `@inject` only for light template wiring.
69+
- Use `json(...)` for JS/JSON literal output in templates.
70+
71+
---
72+
73+
## Project Overrides
74+
75+
Add app-specific or third-party rules here. Keep short and scoped.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 switon.dev
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Switon App Starter
2+
3+
Official starter for a new Switon application.
4+
5+
## Installation
6+
7+
```bash
8+
composer create-project switon/skeleton my-app
9+
cd my-app
10+
```
11+
12+
## Run
13+
14+
```bash
15+
php public/index.php
16+
```
17+
18+
`create-project` creates `.env` from `.env.example` and generates `MASTER_KEY`. `.env` defaults `SERVER_TYPE=php` for the built-in PHP server.
19+
20+
Then open:
21+
22+
- `http://127.0.0.1:9501/` — welcome JSON
23+
- `http://127.0.0.1:9501/time/current` — sample route
24+
25+
## CLI
26+
27+
```bash
28+
bash bin/console tool:list
29+
bash bin/console router:list --json
30+
```
31+
32+
On Windows when shell wrapper execution is unavailable, use `php switon.php` instead of `bash bin/console`.
33+
34+
## Start Here
35+
36+
- `switon.yml` defines app metadata, route prefixes, server options, and default filters.
37+
- `app/Controller/` contains the example controllers.
38+
- add `config/*.php` only when you need PHP-only configuration patches.
39+
- `public/index.php` is the HTTP entrypoint.
40+
41+
Docs: https://docs.switon.dev/latest/tutorial

app/Controller/Controller.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Controller;
6+
7+
use Switon\Core\Attribute\Autowired;
8+
use Switon\Http\RequestInterface;
9+
use Switon\Http\ResponseInterface;
10+
use Switon\Principal\IdentityInterface;
11+
12+
class Controller extends \Switon\Http\Controller
13+
{
14+
#[Autowired] protected RequestInterface $request;
15+
#[Autowired] protected ResponseInterface $response;
16+
#[Autowired] protected IdentityInterface $identity;
17+
}

app/Controller/IndexController.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Controller;
6+
7+
use Switon\Authorizing\Attribute\Authorize;
8+
use Switon\Routing\Attribute\GetMapping;
9+
use Switon\Routing\Attribute\RequestMapping;
10+
11+
#[Authorize(Authorize::ANONYMOUS)]
12+
#[RequestMapping('')]
13+
class IndexController extends Controller
14+
{
15+
#[GetMapping('/')]
16+
public function indexAction(): array
17+
{
18+
return ['message' => 'Welcome to Switon'];
19+
}
20+
}

0 commit comments

Comments
 (0)