diff --git a/CLAUDE.md b/CLAUDE.md
index aff583f..fe6cd27 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -886,6 +886,42 @@ MySQL backup credentials stored in `/etc/mysql/backup.cnf` (mode 600, owned by `
---
+## Development Rules
+
+The following rules are mandatory for all development on this codebase. Violations have caused production 500 errors.
+
+**Rule 1 — Never assume, always read first.**
+Before fixing any error or touching any file, read the actual file content on disk. Do not assume the file matches what was previously written — the server may have a different version. Use `cat`, `grep`, or `sed -n` to read the exact content before making any changes.
+
+**Rule 2 — No temporary fixes.**
+All fixes must address the root cause. Workarounds that mask a problem without solving it are not permitted. If the root cause is unclear, investigate further before writing any code.
+
+**Rule 3 — Never remove or change existing functionality unless explicitly instructed.**
+All changes must be additive or corrective. Existing routes, function names, variable names, and model fields must be preserved unless a change is explicitly requested.
+
+**Rule 4 — Always audit the full extends chain in every template you create or modify.**
+Every `{% extends "..." %}` path must resolve relative to the Flask app's `template_folder` root. Before delivering any template, verify the parent template exists at that exact path. Correct convention for this project: `admin/layouts/base.html` for admin templates, `tenant/layouts/base.html` for tenant templates.
+
+**Rule 5 — Never leave `url_for()` calls pointing at unregistered or stub-only endpoints.**
+If a blueprint is registered as a stub (no routes yet), all `url_for()` references to its endpoints in templates must be replaced with `'#'` or guarded with `{% if %}` until the route is implemented. A `BuildError` from an unregistered endpoint is a 500 error in production.
+
+**Rule 6 — Always add logging for create, edit, and delete actions.**
+Every route that creates, edits, deletes, or changes the status of a record must call `logger.info()` or `logger.warning()` with the action, relevant IDs, and actor context.
+
+**Rule 7 — All audit log values must be JSON-serialisable.**
+When passing data to `AuditLog.log()` or any JSON column, always convert `datetime`/`date` to ISO-8601 strings via `.isoformat()` and `Decimal` to `float`. Use `model_to_dict()` from `app/admin/utils.py` — never pass raw ORM objects.
+
+**Rule 8 — Use absolute paths for `template_folder` and `static_folder` in app factories.**
+Never use relative paths (`"../templates"`) in Flask app factories. Flask resolves relative paths against the package directory, not the project root, which differs depending on where Gunicorn is started. Always use `os.path.dirname(os.path.abspath(__file__))` as the anchor.
+
+**Rule 9 — Test all fixes before delivering them.**
+Every fix must be validated by a programmatic test (import test, render test, or unit test) before being packaged for delivery. Do not ship code that has not been executed in the container.
+
+**Rule 10 — Pack files when more than 5 files are changed.**
+When a fix touches more than 5 files, compress them into a ZIP for delivery. Always include only the changed files — not the entire project.
+
+---
+
## Phase 1 — Implementation Notes
The following decisions and resolutions were made during Phase 1 scaffold implementation.
@@ -952,4 +988,4 @@ All Phase 2+ blueprints are registered as stubs (blueprint object only, no route
| 24 | Admin login URL | Admin auth blueprint uses `url_prefix=""`. Login page is at `posadmin.ngodanguyen.tech/login`. Root `/` redirects to `/login` (unauthenticated) or `/dashboard` (authenticated). |
| 25 | JWT blocklist table location | `jwt_blocklist` defined in `platform.py` (not `salon.py`) — it is a platform-level concern shared across all tenants. DB-persisted (not in-memory) to survive Gunicorn worker restarts. |
| 26 | Template path convention | `template_folder` points to project-root `templates/`. All `render_template()` calls and `{% extends %}` use full paths: `"admin/auth/login.html"`, `"admin/layouts/base.html"`, `"tenant/auth/login.html"`, etc. |
-| 27 | Production domains | Admin portal: `posadmin.ngodanguyen.tech`. Tenant portal: `pos.ngodanguyen.tech`. Updated in `.env`, `nginx.conf`, and all documentation. |
+| 27 | Production domains | Admin portal: `posadmin.ngodanguyen.tech`. Tenant portal: `pos.ngodanguyen.tech`. Updated in `.env`, `nginx.conf`, and all documentation. |
\ No newline at end of file
diff --git a/app/templates/tenant/auth/account_locked.html b/app/templates/tenant/auth/account_locked.html
index 3250c4c..562ed1f 100644
--- a/app/templates/tenant/auth/account_locked.html
+++ b/app/templates/tenant/auth/account_locked.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Account Suspended{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/auth/cancelled.html b/app/templates/tenant/auth/cancelled.html
index 5a19122..603d855 100644
--- a/app/templates/tenant/auth/cancelled.html
+++ b/app/templates/tenant/auth/cancelled.html
@@ -1,4 +1,4 @@
-{% extends "tenant/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Account Cancelled{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/auth/login.html b/app/templates/tenant/auth/login.html
index 260a9e5..5bb56f5 100644
--- a/app/templates/tenant/auth/login.html
+++ b/app/templates/tenant/auth/login.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Sign In{% endblock %}
{% block content %}
@@ -44,9 +44,7 @@
Forgot password?
-
- View demo account
-
+
diff --git a/app/templates/tenant/auth/password_reset_confirm.html b/app/templates/tenant/auth/password_reset_confirm.html
index 4c938c6..1c30f62 100644
--- a/app/templates/tenant/auth/password_reset_confirm.html
+++ b/app/templates/tenant/auth/password_reset_confirm.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Set New Password{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/auth/password_reset_request.html b/app/templates/tenant/auth/password_reset_request.html
index 96dd2fd..5e5c090 100644
--- a/app/templates/tenant/auth/password_reset_request.html
+++ b/app/templates/tenant/auth/password_reset_request.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Reset Password{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/auth/suspended.html b/app/templates/tenant/auth/suspended.html
index 0a6c4d8..1252325 100644
--- a/app/templates/tenant/auth/suspended.html
+++ b/app/templates/tenant/auth/suspended.html
@@ -1,4 +1,4 @@
-{% extends "tenant/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Account Suspended{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/dashboard/index.html b/app/templates/tenant/dashboard/index.html
index 7727702..ddc17d2 100644
--- a/app/templates/tenant/dashboard/index.html
+++ b/app/templates/tenant/dashboard/index.html
@@ -1,4 +1,4 @@
-{% extends "tenant/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
Dashboard
diff --git a/app/templates/tenant/feature_unavailable.html b/app/templates/tenant/feature_unavailable.html
index e2caebf..0d1deeb 100644
--- a/app/templates/tenant/feature_unavailable.html
+++ b/app/templates/tenant/feature_unavailable.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Feature Unavailable{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/layouts/base.html b/app/templates/tenant/layouts/base.html
index 34564f3..ed22b7f 100644
--- a/app/templates/tenant/layouts/base.html
+++ b/app/templates/tenant/layouts/base.html
@@ -37,7 +37,7 @@
{% for loc in locations %}
+ href="{{ '#' }}">
{{ loc.name }}
{% if loc.is_primary %}Primary{% endif %}
@@ -86,74 +86,74 @@
+ href="{{ '#' }}">
Appointments
+ href="{{ '#' }}">
POS / Checkout
+ href="{{ '#' }}">
Customers
+ href="{{ '#' }}">
Staff
+ href="{{ '#' }}">
Services & Products
+ href="{{ '#' }}">
Inventory
+ href="{{ '#' }}">
Gift Cards
+ href="{{ '#' }}">
Reconciliation
+ href="{{ '#' }}">
Reports
{% if current_user.role == 'tenant_admin' %}
+ href="{{ '#' }}">
Marketing
+ href="{{ '#' }}">
Locations
+ href="{{ '#' }}">
Settings
diff --git a/app/templates/tenant/staff_auth/login.html b/app/templates/tenant/staff_auth/login.html
index f555f5d..61792df 100644
--- a/app/templates/tenant/staff_auth/login.html
+++ b/app/templates/tenant/staff_auth/login.html
@@ -1,4 +1,4 @@
-{% extends "tenant/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Staff Login{% endblock %}
{% block content %}
diff --git a/app/templates/tenant/staff_auth/staff_login.html b/app/templates/tenant/staff_auth/staff_login.html
index a3fca4f..fb952e7 100644
--- a/app/templates/tenant/staff_auth/staff_login.html
+++ b/app/templates/tenant/staff_auth/staff_login.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Staff Login{% endblock %}
{% block content %}
diff --git a/templates/tenant/auth/account_locked.html b/templates/tenant/auth/account_locked.html
index 3250c4c..562ed1f 100644
--- a/templates/tenant/auth/account_locked.html
+++ b/templates/tenant/auth/account_locked.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Account Suspended{% endblock %}
{% block content %}
diff --git a/templates/tenant/auth/login.html b/templates/tenant/auth/login.html
index 260a9e5..5bb56f5 100644
--- a/templates/tenant/auth/login.html
+++ b/templates/tenant/auth/login.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Sign In{% endblock %}
{% block content %}
@@ -44,9 +44,7 @@
Forgot password?
-
- View demo account
-
+
diff --git a/templates/tenant/auth/password_reset_confirm.html b/templates/tenant/auth/password_reset_confirm.html
index 4c938c6..1c30f62 100644
--- a/templates/tenant/auth/password_reset_confirm.html
+++ b/templates/tenant/auth/password_reset_confirm.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Set New Password{% endblock %}
{% block content %}
diff --git a/templates/tenant/auth/password_reset_request.html b/templates/tenant/auth/password_reset_request.html
index 96dd2fd..5e5c090 100644
--- a/templates/tenant/auth/password_reset_request.html
+++ b/templates/tenant/auth/password_reset_request.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Reset Password{% endblock %}
{% block content %}
diff --git a/templates/tenant/feature_unavailable.html b/templates/tenant/feature_unavailable.html
index e2caebf..0d1deeb 100644
--- a/templates/tenant/feature_unavailable.html
+++ b/templates/tenant/feature_unavailable.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Feature Unavailable{% endblock %}
{% block content %}
diff --git a/templates/tenant/layouts/base.html b/templates/tenant/layouts/base.html
index 34564f3..ed22b7f 100644
--- a/templates/tenant/layouts/base.html
+++ b/templates/tenant/layouts/base.html
@@ -37,7 +37,7 @@
{% for loc in locations %}
+ href="{{ '#' }}">
{{ loc.name }}
{% if loc.is_primary %}Primary{% endif %}
@@ -86,74 +86,74 @@
+ href="{{ '#' }}">
Appointments
+ href="{{ '#' }}">
POS / Checkout
+ href="{{ '#' }}">
Customers
+ href="{{ '#' }}">
Staff
+ href="{{ '#' }}">
Services & Products
+ href="{{ '#' }}">
Inventory
+ href="{{ '#' }}">
Gift Cards
+ href="{{ '#' }}">
Reconciliation
+ href="{{ '#' }}">
Reports
{% if current_user.role == 'tenant_admin' %}
+ href="{{ '#' }}">
Marketing
+ href="{{ '#' }}">
Locations
+ href="{{ '#' }}">
Settings
diff --git a/templates/tenant/staff_auth/staff_login.html b/templates/tenant/staff_auth/staff_login.html
index a3fca4f..fb952e7 100644
--- a/templates/tenant/staff_auth/staff_login.html
+++ b/templates/tenant/staff_auth/staff_login.html
@@ -1,4 +1,4 @@
-{% extends "layouts/base.html" %}
+{% extends "tenant/layouts/base.html" %}
{% block title %}Staff Login{% endblock %}
{% block content %}