05/06 Updated markdown files
This commit is contained in:
@@ -6,8 +6,8 @@ A multi-tenant SaaS POS web application for nail salons, served across two dedic
|
||||
|
||||
| Domain | Audience | Purpose |
|
||||
|---|---|---|
|
||||
| `admin.mydomain.com` | System Admins | Platform management |
|
||||
| `mydomain.com` | Tenant users | Salon management |
|
||||
| `posadmin.ngodanguyen.tech` | System Admins | Platform management |
|
||||
| `pos.ngodanguyen.tech` | Tenant users | Salon management |
|
||||
|
||||
---
|
||||
|
||||
@@ -93,6 +93,8 @@ flask --app wsgi_tenant:app db upgrade
|
||||
|
||||
### 7. Seed initial data (plans + superadmin)
|
||||
|
||||
> **Important:** There is no default seeded admin user. You must create one manually using the shell commands below. Choose a strong password — minimum 10 characters, at least one uppercase letter, one lowercase letter, and one digit.
|
||||
|
||||
```bash
|
||||
flask --app wsgi_admin:app shell
|
||||
```
|
||||
@@ -160,9 +162,6 @@ sudo chown salonpos:salonpos /var/log/salon_pos_admin /var/log/salon_pos_tenant
|
||||
sudo cp deploy/salon_pos_admin.service /etc/systemd/system/
|
||||
sudo cp deploy/salon_pos_tenant.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo mkdir -p /run/salon_pos
|
||||
sudo chown salonpos:salonpos /run/salon_pos
|
||||
sudo chmod 775 /run/salon_pos
|
||||
sudo systemctl enable salon_pos_admin salon_pos_tenant
|
||||
sudo systemctl start salon_pos_admin salon_pos_tenant
|
||||
sudo systemctl status salon_pos_admin salon_pos_tenant
|
||||
@@ -263,14 +262,38 @@ pip install -r requirements.txt
|
||||
cp .env.example .env
|
||||
# Set FLASK_ENV=development in .env
|
||||
flask --app wsgi_tenant:app db upgrade
|
||||
flask --app wsgi_tenant:app run --port 5001
|
||||
flask --app wsgi_admin:app run --port 5002
|
||||
flask --app wsgi_tenant:app run --port 5001 # Tenant portal → http://localhost:5001/login
|
||||
flask --app wsgi_admin:app run --port 5002 # Admin portal → http://localhost:5002/login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
## Phase 1 Resolutions
|
||||
|
||||
The following issues were encountered and resolved during Phase 1 — documented here to inform future contributors.
|
||||
|
||||
### Circular Foreign Keys (MySQL InnoDB)
|
||||
`appointments.rebooked_from_transaction_id` and `transactions.appointment_id` form a circular FK dependency. MySQL InnoDB enforces FK constraints at `CREATE TABLE` time so neither table could be created first. **Fix:** both columns use `use_alter=True, name="fk_..."` so SQLAlchemy defers them as `ALTER TABLE` statements after all tables are created.
|
||||
|
||||
If you re-generate migrations from scratch, always verify with:
|
||||
```bash
|
||||
flask --app wsgi_tenant:app db upgrade
|
||||
```
|
||||
Any `(1824, "Failed to open the referenced table ...")` error means a circular FK is missing `use_alter=True`.
|
||||
|
||||
### Static File Double-Prefix
|
||||
Flask apps with `static_folder="../static"` and `static_url_path="/static/admin"` produce URLs like `/static/admin/css/admin.css`. If templates then call `url_for('static', filename='admin/css/admin.css')` the URL becomes `/static/admin/admin/css/admin.css` (doubled prefix). **Fix:** each app points `static_folder` directly at its subdirectory (`static/admin/` or `static/tenant/`) with `static_url_path="/static"`. Templates use `url_for('static', filename='css/admin.css')` with no portal prefix in the filename.
|
||||
|
||||
### Content Security Policy and Bootstrap CDN
|
||||
The CSP must explicitly allow `https://cdn.jsdelivr.net` in `script-src`, `style-src`, and `font-src`. Both `app/security.py` (Flask after-request hook) and `deploy/nginx.conf` must be consistent — Nginx headers override Flask headers in production.
|
||||
|
||||
### Admin Login URL
|
||||
The admin portal login page is at `posadmin.ngodanguyen.tech/login` (not `/admin/login`). The admin auth blueprint uses `url_prefix=""`. Visiting `/` redirects to `/login`.
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
salon_pos/
|
||||
├── app/
|
||||
@@ -283,8 +306,8 @@ salon_pos/
|
||||
│ ├── models/
|
||||
│ │ ├── platform.py # SystemUser, Tenant, Plan, AuditLog, ...
|
||||
│ │ └── salon.py # All tenant-scoped models
|
||||
│ ├── admin/ # admin.mydomain.com blueprints
|
||||
│ └── tenant/ # mydomain.com blueprints
|
||||
│ ├── admin/ # posadmin.ngodanguyen.tech blueprints
|
||||
│ └── tenant/ # pos.ngodanguyen.tech blueprints
|
||||
├── config.py # Dev / Prod / Test config classes
|
||||
├── wsgi_admin.py # Gunicorn entrypoint — admin
|
||||
├── wsgi_tenant.py # Gunicorn entrypoint — tenant
|
||||
@@ -292,4 +315,4 @@ salon_pos/
|
||||
├── .env.example
|
||||
├── deploy/ # systemd units, Nginx config, backup scripts
|
||||
└── tests/ # pytest test suites
|
||||
```
|
||||
```
|
||||
Reference in New Issue
Block a user