2ae1c867b55613ff2404bbc6c9a66d0ea7cd10ba
User goal: from the Shop Floor Terminal lock screen, a user with no PIN (or who forgot their PIN) should be able to set / reset their own PIN without a manager's help. Today, FpPinSetup runs only from Preferences which requires being logged in — there's no path from the lock screen. Design (approved, with user-picked defaults): - Tap tile of no-PIN user -> 'Send temporary PIN' button -> email 4-digit code, valid 72 hours -> enter code -> choose new PIN -> auto-login. - For existing-PIN users: 3 failed PIN entries -> 'Forgot? Reset PIN via email' button appears below keypad -> same email flow. - Both flows merge at: enter temp code -> set new PIN. - Email goes to res.users.login (or partner_id.email fallback). No-email-on-file -> 'Contact your manager: <owner>' message. - Rate limit: 3 requests per user per rolling 60 min. - Per-code cap: 5 wrong attempts invalidates the code. - New model fp.tablet.pin.reset stores hashed code + expires_at with SQL constraint enforcing one-active-row-per-user. - 2 new endpoints (request_reset_code, verify_reset_code) + extend existing /fp/tablet/set_pin to accept reset_token alternative to old_pin. - Audit: 3 new event_type values on fp.tablet.session.event. - Reuses existing PBKDF2 helpers, FpPinPad component (mode prop), fp.notification.template dispatch, mail.template pattern. Per CLAUDE.md Rule 25 the mail template references ONLY core res.users fields (object.name, object.email, object.login, object.company_id) — ctx.code is dispatched as extra_context, not a model field. Safe at parse-time. Self-review fixed 2 issues: - event_kind -> event_type (real field name on fp.tablet.session.event) - Listed existing event_type values explicitly for context Spec: docs/superpowers/specs/2026-05-25-tablet-pin-self-service-design.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
Odoo 19 custom modules
Languages
Python
56.7%
HTML
25.2%
JavaScript
14.8%
SCSS
2.1%
CSS
0.8%
Other
0.3%