Sistema MRP uses bcrypt password hashing, server-side sessions stored in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ElthonJohan/Sistema-MRP/llms.txt
Use this file to discover all available pages before exploring further.
user_sessions database table, and URL-based token passing via st.query_params["token"]. Two roles — superadmin and cliente — are enforced by guard functions called at the top of every page.
Login
Passwords are hashed with bcrypt at 12 rounds. On a successful login, the server creates a record in theuser_sessions table and places the opaque session token in the URL as st.query_params["token"]. The token is the only credential the browser carries forward.
Session persistence
init_session() in utils/session_manager.py is called at the top of every page (via the guard functions). It reads the token from the URL, looks up the matching row in user_sessions, and populates st.session_state with user_id, username, and role.
Read token from URL
init_session() reads st.query_params.get("token"). If absent, the session is considered invalid.Validate against database
The token is looked up in
user_sessions. A valid session must exist and must not be expired.Check inactivity expiry
get_valid_session() enforces a 30-minute inactivity window. If last_activity is more than 30 minutes ago the session is invalidated server-side and the user is redirected to login.Account lockout
To limit brute-force attacks, failed login attempts are counted per account:- 5 consecutive failed attempts locks the account for 15 minutes.
- The lockout is tracked server-side in the database; clearing cookies does not bypass it.
- After 15 minutes the counter resets automatically and the account unlocks.
Roles
Two roles exist, stored inUser.role, propagated to UserSession.role, and available at runtime in st.session_state.role.
| Role | Default landing page | Data scope |
|---|---|---|
superadmin | pages/admin.py | Global — all clients visible |
cliente | pages/dashboard.py | Scoped to own warehouses (Warehouse.owner_id == user_id) |
init_db.py with username superadmin and initial password Admin123!. It cannot be deleted.
Protecting a page
Call one of the guard functions as the very first statement in any page file. Do not add logic before the guard.| Guard | Use on |
|---|---|
require_login() | Pages accessible to any authenticated user |
require_cliente() | All operational pages (requirements, dispatch, inventory, …) |
require_superadmin() | Admin-only pages such as pages/access_logs.py |
Impersonation
A superadmin can click Visualizar onpages/admin.py to view the application as a specific client. This sets st.session_state["impersonating"] = True and st.session_state["impersonating_user_id"] to the target client’s ID.
get_current_user_id() automatically returns impersonating_user_id while impersonation is active, so every warehouse query is scoped to the impersonated client without any additional changes in the service layer. require_cliente() also allows the superadmin through when impersonating is True.