Config backup, a Docker dev/prod split, and a Gitea-built release image.
Added
- /settings -> General -> "Configuration backup": JSON export/import of the
panel's general settings + attribute definitions
(App\Services\ConfigBackupService); audited as config.export / config.import.
Export can leave out the attribute-encryption key. No AD data included.
- docker/compose.dev.yaml: live-reload dev stack that bind-mounts the working
tree. docker/php/Dockerfile is now multi-stage (base -> dev / prod).
- .github/workflows/release.yml: on every vX.Y.Z tag, builds the prod image and
pushes gitea.kzbikowski.pl/kzbkowski/adconsole:{X.Y.Z,X.Y,latest}.
Changed
- docker/compose.yaml: self-contained prod image (app code + composer install
--no-dev baked in via COPY); persistent state in docker/data/{app_storage,db};
defaults to the released image (ADCONSOLE_VERSION pins a tag, ADCONSOLE_IMAGE
replaces the ref). Apache now honours public/.htaccess (AllowOverride All).
Run from the repo root with --env-file .env.
- Repo root now holds only README.md; CHANGELOG / CONTRIBUTING / SECURITY /
CODE_OF_CONDUCT moved under docs/.
Upgrade notes: docs/upgrading.md#v110--docker-layout. Full log: docs/CHANGELOG.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKT9p3bfP8RZesExdYCS52
133 lines
4.8 KiB
Markdown
133 lines
4.8 KiB
Markdown
# Development
|
|
|
|
## Local setup
|
|
|
|
```sh
|
|
git clone https://gitea.kzbikowski.pl/kzbkowski/ADconsle.git adconsole && cd adconsole
|
|
composer install
|
|
cp .env.example .env
|
|
php artisan key:generate
|
|
```
|
|
|
|
Edit `.env` for a dev box:
|
|
|
|
```
|
|
APP_ENV=local
|
|
APP_DEBUG=true
|
|
LOG_LEVEL=debug
|
|
DB_CONNECTION=sqlite # simplest; then: touch database/database.sqlite
|
|
```
|
|
|
|
```sh
|
|
php artisan migrate
|
|
php artisan serve
|
|
```
|
|
|
|
You still need a reachable domain controller for the AD-backed screens. Without
|
|
one, the auth and list pages will error — the test suite does **not** need a DC
|
|
(it fakes the guard and mocks LdapRecord).
|
|
|
|
## Local setup — Docker (live reload)
|
|
|
|
```sh
|
|
git clone https://gitea.kzbikowski.pl/kzbkowski/ADconsle.git adconsole && cd adconsole
|
|
cp .env.example .env # APP_ENV=local, APP_DEBUG=true, real LDAP_* / AD_*
|
|
docker compose --env-file .env -f docker/compose.dev.yaml up --build
|
|
```
|
|
|
|
Run from the repo root; `--env-file .env` lets Compose interpolate `${DB_*}`
|
|
from the repo-root `.env` (the file lives in `docker/`). Set
|
|
`export COMPOSE_FILE=docker/compose.dev.yaml COMPOSE_ENV_FILES=.env` once to
|
|
drop the flags.
|
|
|
|
The working tree is bind-mounted over `/var/www/html`, so PHP / Blade / CSS / JS
|
|
edits apply on the next request (the `dev` image target sets
|
|
`opcache.revalidate_freq=0`). On the first boot of a fresh clone the entrypoint
|
|
runs `composer install` (with dev deps) and `php artisan key:generate`, then
|
|
`migrate`. `vendor/` lands back on the host, so your IDE resolves it too.
|
|
|
|
Database and `storage/` are throwaway named volumes — add `-v` to
|
|
`docker compose … down` to reset the box. MariaDB is published on
|
|
`localhost:3306`. Run artisan / tools inside the container:
|
|
|
|
```sh
|
|
docker compose --env-file .env -f docker/compose.dev.yaml exec app php artisan migrate:fresh
|
|
docker compose --env-file .env -f docker/compose.dev.yaml exec app php artisan test
|
|
docker compose --env-file .env -f docker/compose.dev.yaml exec app vendor/bin/pint
|
|
```
|
|
|
|
`compose.dev.yaml` expects an external Traefik on `traefik_public`; without one,
|
|
`cp docker/compose.dev.override.yaml.template docker/compose.dev.override.yaml`
|
|
and add `-f docker/compose.dev.override.yaml` (publishes `http://localhost:8080`).
|
|
|
|
## Tests
|
|
|
|
```sh
|
|
php artisan test # everything (~40, SQLite :memory:)
|
|
php artisan test --filter=Dashboard # one file / group
|
|
composer test # config:clear + test
|
|
```
|
|
|
|
- `tests/Unit` — pure logic (`LdapAttributeHelper`, `AttributeCipher`,
|
|
`MemberOfLoginGroup`, `OuTreeService`).
|
|
- `tests/Feature` — HTTP: auth, localisation, the About page, attribute config,
|
|
the audit log and the user CSV export (`RefreshDatabase`), and the dashboard
|
|
(seeds the `file` cache, no LDAP).
|
|
- `tests/TestCase::actingAsPanelAdmin()` logs in a fake `App\Ldap\User` on the
|
|
`ldap` guard so you can hit protected routes.
|
|
|
|
PHPUnit tags every test `DEPR` because PHP 8.5 deprecates a PDO constant PHPUnit
|
|
touches. It is **not** a failure — look at the `Tests:` summary line.
|
|
|
|
## Code style
|
|
|
|
[Laravel Pint](https://laravel.com/docs/pint):
|
|
|
|
```sh
|
|
vendor/bin/pint # fix
|
|
vendor/bin/pint --test # check only (CI)
|
|
composer lint / composer format
|
|
```
|
|
|
|
Match the surrounding code: constructor property promotion, typed properties,
|
|
short closures, `App\Services` for cross-cutting logic. Comments in the codebase
|
|
are Polish — keep new ones consistent with the file you're editing.
|
|
|
|
## Adding a translation string
|
|
|
|
1. Add the key to **both** `lang/pl/<ns>.php` and `lang/en/<ns>.php`.
|
|
2. Use `__('<ns>.<key>')` in Blade/PHP — never inline copy.
|
|
3. Some existing `lang/pl/*` values are asserted verbatim by
|
|
`tests/Feature/AttributeConfigTest` and `AboutPageTest`; run the suite after
|
|
touching PL strings.
|
|
|
|
## Adding an AD attribute to the UI
|
|
|
|
No code change needed for a plain attribute: `/settings` → **Attributes** →
|
|
add key / label / `ldap` name / category / type / column. Computed or
|
|
specially-encoded attributes (bit flags, FileTime) need a helper in
|
|
`App\Services\LdapAttributeHelper` and wiring in the relevant controller.
|
|
|
|
## Front-end
|
|
|
|
`public/css/style.css` and `public/js/main.js` are edited directly and served
|
|
as-is — no build step. Keep the light/dark (`data-bs-theme`) treatment working
|
|
for anything new: define colours as tokens on `:root` and override under
|
|
`[data-bs-theme="dark"]`.
|
|
|
|
## Database changes
|
|
|
|
New migrations go in `database/migrations`. Remember the project rule: **no AD
|
|
data in SQL** — migrations are for app infrastructure and `panel_settings`-style
|
|
config only. `PanelSettingsService` is the access point for panel config; don't
|
|
read the table directly from controllers.
|
|
|
|
## Handy commands
|
|
|
|
```sh
|
|
php artisan route:list --path=users
|
|
php artisan tinker
|
|
php artisan optimize:clear # after .env / config edits
|
|
php artisan migrate:fresh # dev DB reset (infra tables only)
|
|
```
|