This is a small scale Point of Sale systemn designed for a school canteen.
It also served as a learning experience to see how certain capabilities can be used together.
- Design principles and considerations
- Technologies Used
- User Roles Required
- Connectivity Requirements
- Setup Dev
- Setup Prod
- Todo
- Lessons Learned
The following design principles apply
- It needs to be simple to setup and manage. Canteen staff are not IT nerds
- Intermittened connections should not cause failures
- Database backups should be seamless
- Vue for the reactive web front-end capabilities
- Vuex for session management
- Vue Router for front-end routing
- Vue components using javascript files
- Bootstrap 4 for widgets
- Material Icons
- Charts.js for report charts
- No webpacks yet...
- CouchDB as the central database (needs setup wizard first run)
- CouchDB views for reports using simple Map/Reduce jobs
- PouchDB for the client side database
- Filters to manage record synchronisation and direction
create BD
curl -X PUT http://admin:password@localhost:8080/couchdb/swanepos
- Progressive Web App principles and service workers
- Couch DB authentication
- Role: pos: Use Point of Sale capability only
- Role: admin: Can manage products, view sales and reports
- Role: superadmin: Can create views and populate reference data from the App
- Authentication requires connectivity
- Once authenticated: ** Point of Sale writes to PouchDB -> Sales are synchronised up to Couch DB ** Product management writes to PouchDB <-> Two way synchronisation
- Reports require online connectivity and talks to CouchDB directly
- Database: CouchDB - good tutorial: https://pouchdb.com/guides/setup-couchdb.html
- Progressive Web Apps: A compatible browser
- Web server: I used built in Python SimpleHTTPServer
- podman
The new setup for dev uses podman to deploy Couch DB, you can include nginx in that but for that you require DNS enabled in podman.
For development purposes the containers will run in the same pod, so after build run.
# start couch db
podman run -d --pod new:devpod --name vue-couchdb -p 5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password localhost/couchdb
# start nginx
podman run -d --pod devpod --name nginx_pos -p 8443:8443 -p 8080:8080 localhost/nginx_pos
You can use Ansible for a super quick start
Create a variables.yaml file by copying sample_variables.yaml and set:
- host_ip: xxx.xxx.xxx.xxx
- couchdb_admin_user: yourusername
- couchdb_admin_password: yourpassword
- couchdb_volume: storecouchdbdatahere
Install: containers.podman ansible collection
ansible-galaxy collection install containers.podman
Build the containers
# Build database
ansible-playbook main.yaml --tags "import_vars, build_couch_image"
# Build the frontend
ansible-playbook main.yaml --tags "import_vars, build_pos_image"
Start app components independently
# Start database
ansible-playbook main.yaml --tags "import_vars, create_couch"
# Start the frontend
ansible-playbook main.yaml --tags "import_vars, create_pos"
Stop all
ansible-playbook main.yaml --tags "import_vars, stop_all"
Start all
ansible-playbook main.yaml --tags "import_vars, start_all"
Rebuild and redeploy pos Image
ansible-playbook main.yaml --tags "import_vars, rebuild_pos"
Remove container and images from your setup
ansible-playbook main.yaml --tags "import_vars, clean"
-
Create 3 users
-
Replace values ** username: Choose a name ** display name: Choose a name ** plaintext_password: Choose a password
-
Role: posadmin . This user requires database access privileges. You can do this in the CouchDB UI. The use document could look like this
{
"_id": "org.couchdb.user:posadmin",
"name": "display name",
"type": "user",
"roles": ['admin'],
"password": "plaintext_password"
}
curl -X PUT http://admin:password@localhost:8080/couchdb/_users/org.couchdb.user:posadmin \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "posadmin", "password": "password", "roles": ["admin"], "type": "user"}'
- Role: superadmin . This user requires database admin privileges. You can do this in the CouchDB UI
{
"_id": "org.couchdb.user:superadmin",
"name": "display name",
"type": "user",
"roles": ['superAdmin'],
"password": "password"
}
curl -X PUT http://admin:password@localhost:8080/couchdb/_users/org.couchdb.user:superadmin \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "superadmin", "password": "password", "roles": ["superAdmin"], "type": "user"}'
- Role: pos . This user requires database access privilages. You can do this in the CouchDB UI
{
"_id": "org.couchdb.user:posuser",
"name": "display name",
"type": "user",
"roles": ['pos'],
"password": "plaintext_password"
}
curl -X PUT http://admin:password@localhost:8080/couchdb/_users/org.couchdb.user:posuser \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name": "posuser", "password": "password", "roles": ["pos"], "type": "user"}'
- Add users to database roles ** Then you can create per database authentication by creating document with id "_security" in specific database which is not versioned, e.g. ** members are normal users, they can query and update data. This example pos and posadmin ** admins are special users, that can create views and design documents. This example posadmin
curl -X PUT http://admin:password@localhost:8080/couchdb/swanepos/_security \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"members":{"names":["posuser","posadmin","superadmin"],"roles":[]},"admins":{"names":["posadmin","superadmin"]}}'
test users
curl -u [user]:[password] http://localhost:8080/couchdb/swanepos/_all_docs
Currently there are Container build files for
- CouchDB
- Nginx
- Start using podman
Options being considered
- Couch-as-a-Service: GCP, IBM Cloud?, with a webserver to serve content
- Couch, proxy/webserver (Candy) on a RaspberryPi with Wifi Hotspot
- Small Intel based NUC with Podman or Kubernetes to serve components
Client-side
- Android or IPad devices would work fine
- Build out reports
- Build containerised pattern using Podman and Buildah - built
- Build out skaffold or similar patterns for kubernetes
- Build kubernetes files likely targetting OpenShift
- Vue Router using JS files
- Vue components - there is a better way, but hey
- Vuex session management
- Replication managed direction using filters and removing local copies
- CouchDB logical "_id" fields
- Pagination using id fields and an array
- CouchDB authentication
- Views and Map/Reduce jobs in CouchDB
- Vue Lifecycle: Mounted, Created ect
- Vue Computed Fields - Official doco. Keep complex logic away from template.
- Vue Filters - Official doco. Useful to format data
- Progresive Web Apps - Did this without special plugins
- Couch/Pouch Database design thoughts
- CouchDB Container File