<p><img height="100" src="./public/logo.png"></p>

# TinyPOS

A simple Point of Sale

## Installation

- Clone project
- Go to the folder application using cd command on your cmd or terminal
- Run `composer install` on your cmd or terminal
- Copy `.env.example` file to `.env` on the root folder.
  You can type copy .env.example .env if using command prompt Windows
  or `cp .env.example .env` if using terminal, Ubuntu
- Open your `.env` file and change the database name (`DB_DATABASE`) to whatever you have,
  username (`DB_USERNAME`) and password (`DB_PASSWORD`) field correspond to your configuration.
- Run `php artisan key:generate`
- Run `php artisan migrate` to create database
- Run `php artisan db:seed` to add default data to database
- Run `php artisan storage:link` to create the symbolic link to your storage folder so that you can access it easier.
- Run `php artisan serve`
- Go to http://localhost:8000/

## Dev server scheduler (cron)

`App\Console\Kernel::schedule` defines the scheduled tasks (currently `Order::summaryLogging()` daily at 00:00 Asia/Ho_Chi_Minh). Laravel 5.6 relies on a system cron entry to trigger them: every minute cron runs `php artisan schedule:run`, which executes only the tasks that are due.

- Repo source of truth: `deploy/cron.d/tnx-pos-dev` (LF line endings enforced by `.gitattributes`).
- Installed target: `/etc/cron.d/tnx-pos-dev`, owned `root:root`, mode `644`.
- The `pos-dev` CI job re-installs the file on **every** deploy, so manual edits on the server are overwritten. Change the repo file instead.
- The job runs as `www-data` — the same user as Apache/mod_php. Any other user would create `storage/logs` / cache files the web server cannot write to (HTTP 500).

### One-time server setup (sudoers)

The GitLab runner needs a scoped sudo grant for the install command. Add it to the existing runner rules with `sudo EDITOR=vi visudo -f /etc/sudoers.d/gitlab-runner-tnxpos` (the file must stay mode `0440`):

```
gitlab-runner ALL=(root) NOPASSWD: /usr/bin/install -m 644 -o root -g root /var/www/html/tnx_pos_2026/dev/pos/src/deploy/cron.d/tnx-pos-dev /etc/cron.d/tnx-pos-dev
```

Then check `sudo visudo -c` and `sudo -l -U gitlab-runner`. Without this rule the `pos-dev` job fails at the `sudo install` step.

### Verify

```
cat /etc/cron.d/tnx-pos-dev
stat -c '%U:%G %a' /etc/cron.d/tnx-pos-dev          # root:root 644
journalctl -u cron -n 5                              # expect "(www-data) CMD (cd /var/www/html/... schedule:run ...)"
cd /var/www/html/tnx_pos_2026/dev/pos/src && sudo -u www-data /usr/bin/php artisan schedule:run
                                                     # expect "No scheduled commands are ready to run."
```

If cron logs `WRONG FILE OWNER` or `bad minute`, the installed file has the wrong owner or CRLF line endings.

Power by Laravel 5.6.