## 1. Dev environment file

- [x] 1.1 Create `.env.dev` at the repo root by copying `.env.example` verbatim, then overriding only the keys listed in 1.2–1.4; verify by diffing against `.env.example` and confirming the Redis, Mail, and Pusher blocks are byte-identical.
- [x] 1.2 Set the app block: `APP_NAME=TNXPOS_DEV`, `APP_ENV=local`, `APP_DEBUG=true`, `APP_URL=http://tnx-pos-dev.w3suga.com:8585`, and `APP_KEY=base64:8yn3YfSobCp6iRtjnWLUyOCYeJ67M0ZnnlB/0Ay8MzE=` (pre-generated via `openssl rand -base64 32`); verify with `grep -c "^APP_KEY=base64:.\{40,\}$" .env.dev` returning 1.
- [x] 1.3 Set the database block: `DB_CONNECTION=mysql`, `DB_HOST=localhost`, `DB_PORT=3306`, `DB_DATABASE=w3s_tnxpos_dev`, `DB_USERNAME=w3suga`, `DB_PASSWORD=Pw@123`; verify by grepping each key resolves to a non-empty value.
- [x] 1.4 Set the remaining dev overrides: `LOG_CHANNEL=daily` and `SESSION_LIFETIME=180`, and confirm the queue key stays `QUEUE_DRIVER=sync` — Laravel 5.6 reads `QUEUE_DRIVER`, not `QUEUE_CONNECTION`, so do not rename it to match `hrm-api`; verify with `grep -q "^QUEUE_DRIVER=" .env.dev && ! grep -q "^QUEUE_CONNECTION=" .env.dev`.
- [x] 1.5 Confirm `.env.dev` is trackable rather than ignored — `.gitignore` must ignore `.env` only; verify with `git check-ignore -v .env.dev` exiting non-zero (no match).

## 2. GitLab CI pipeline

- [x] 2.1 Create `.gitlab-ci.yml` with the `variables` block (`PRJ_NAME: "pos"`, `PRJ_DIR: "/var/www/html/tnx_pos_2026"`, `DEV_DIR: $PRJ_DIR/dev/$PRJ_NAME`) and a single `deploy` stage; verify the file parses as YAML.
- [x] 2.2 Add the `pos-dev` job with `before_script: rm -rf .git` and no Composer step (see design.md — Decisions); verify no `composer` string appears anywhere in the file.
- [x] 2.3 Add the job `script`: remove `$DEV_DIR/src` if present via `sudo rm -rf`, `mkdir -p` it, `\cp -Rf .` into it, `cd` in, promote `.env.dev` to `.env` if present, then run `php artisan migrate`, `storage:link`, `cache:clear`, `config:clear` in that order; verify the four Artisan calls are present and that `passport:keys`, `permissions:autoload`, and `administrative-units:import` are absent.
- [x] 2.4 Add the `after_script` `APP_KEY` sanity check ported from `hrm-api` (grep for a non-empty `APP_KEY`, echoing the "chua co key" / "da co key" branches); verify both branches are present.
- [x] 2.5 Add `rules` restricting the job to `$CI_COMMIT_TAG =~ /^dev-[0-9]{10}$/` with a trailing `when: never`, and `tags: [web_dev]`; verify a sample tag `dev-2608261607` matches the regex and that a branch push matches nothing.

## 3. Repo-level verification

- [x] 3.1 Confirm the change touched only new files — `git status --porcelain` must show exactly two additions (`.gitlab-ci.yml`, `.env.dev`) and zero modifications to pre-existing files.
- [x] 3.2 Commit both files together with a conventional-commit message such as `chore(deploy): add gitlab-ci dev pipeline and .env.dev`; verify with `git show --stat HEAD`.

## 4. Server prerequisites before the first tag

These are host-side and outside the repo; the user has deferred the live test run, so treat this group as a pre-flight checklist rather than work to execute now.

- [x] 4.1 Confirm the runner's PHP CLI is 7.x, not 8.x — Laravel 5.6 will not boot on PHP 8; verify with `php -v` as the runner user on the dev host.
- [x] 4.2 Confirm the `web_dev` runner is available to the `dev/small-projects/tnx-pos` project (not scoped to the `dev/sugahrm` group only); verify in the project's CI/CD → Runners settings.
- [x] 4.3 Create the `w3s_tnxpos_dev` database and grant the `w3suga` account access; verify by connecting with the credentials from `.env.dev`.
- [ ] 4.4 Point a vhost at `/var/www/html/tnx_pos_2026/dev/pos/src/public` matching the host and port in `APP_URL`, backed by a PHP-FPM 7.x pool; verify the vhost resolves.
- [ ] 4.5 Confirm the runner user holds passwordless `sudo rm -rf` over `/var/www/html/tnx_pos_2026`; verify with a dry-run `sudo -n true` and a scoped `sudoers` check.
- [ ] 4.6 Trigger the first deploy with `git tag dev-$(date +%y%m%d%H%M) && git push origin --tags`; verify the `pos-dev` job runs to completion and the `after_script` prints "da co key".
