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
4.8 KiB
Development
Local setup
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
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)
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:
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
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 thefilecache, no LDAP).tests/TestCase::actingAsPanelAdmin()logs in a fakeApp\Ldap\Useron theldapguard 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
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
- Add the key to both
lang/pl/<ns>.phpandlang/en/<ns>.php. - Use
__('<ns>.<key>')in Blade/PHP — never inline copy. - Some existing
lang/pl/*values are asserted verbatim bytests/Feature/AttributeConfigTestandAboutPageTest; 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
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)