diff --git a/packages/fastify/docs/reset_password_flow.md b/packages/fastify/docs/reset_password_flow.md
new file mode 100644
index 0000000..5cf81d6
--- /dev/null
+++ b/packages/fastify/docs/reset_password_flow.md
@@ -0,0 +1,139 @@
+# Reset Password Flow
+
+This document explains how password reset works for **admin** users versus **tenant** (SaaS account) users in this monorepo, with the same assumptions as `user_creation_flow.md`: app profiles live in `users`, and SuperTokens owns credentials and reset tokens.
+
+Typical `saas` config shape (for context—see your app’s `ApiConfig`):
+
+- `saas.mainApp.domain` / `saas.mainApp.subdomain`: main self-service app host.
+- `saas.apps`: optional extra apps (for example **admin**), each with `domain` / `subdomain`.
+- `saas.subdomains`: how hostnames are interpreted (`required` implies real account hosts are expected).
+- `saas.multiDatabase.mode` and `saas.multiDatabase.migrations.path`: whether accounts can use a dedicated DB schema and where account migrations live.
+
+## Components Involved
+
+- `saas/packages/fastify`: account discovery hook, SuperTokens recipe overrides for email/password.
+- `@prefabs.tech/fastify-user`: email sending helpers, reset link path helpers.
+- SuperTokens `thirdpartyemailpassword`: token generation, password update, internal user id.
+
+## Request Context Before `/auth/*`
+
+`accountDiscoveryPlugin` runs on every request unless the host matches a configured **`saas.apps`** entry (for example the admin UI), in which case it **returns immediately** and does **not** set `request.account`, `request.dbSchema`, or `request.authEmailPrefix`.
+
+For other hosts, discovery runs. Defaults in `saas/packages/fastify/src/config.ts` include **`/^\/auth\//`** in `excludeRoutePatterns`:
+
+- **Main app host** (`hostname === saas.mainApp.domain`): if the URL matches an excluded pattern (including `/auth/...`), `discoverAccount` **returns no account** (header-based lookup is skipped in that branch). So `request.account` / `request.authEmailPrefix` are usually **unset** on SuperTokens routes under `/auth/` for the main app host.
+- **Tenant account host** (custom domain or account subdomain): account is resolved **by hostname** even for `/auth/...` routes, so `request.account` and (when applicable) `request.authEmailPrefix` and `request.dbSchema` are set as below.
+
+When an account is resolved and `account.database` is set (tenant schema name, for example `s_xxxxxxxx`), the plugin sets:
+
+- `request.dbSchema = account.database`
+
+When the account has a `slug`, it sets:
+
+- `request.authEmailPrefix = "${account.id}_"` (SuperTokens “logical” email uses this prefix; see `user_creation_flow.md`).
+
+## High-Level Flow (Admin vs Tenant)
+
+```mermaid
+flowchart TD
+ subgraph Admin app host
+ A1[Request to admin app domain] --> A2[Plugin skips discovery]
+ A2 --> A3[No request.account / dbSchema / authEmailPrefix]
+ A3 --> A4[SuperTokens reset APIs use plain email in ST]
+ end
+
+ subgraph Tenant account host
+ T1[Request to account hostname] --> T2[discoverAccount by hostname]
+ T2 --> T3[request.account set]
+ T3 --> T4{account.database?}
+ T4 -->|Yes| T5[request.dbSchema = database name]
+ T4 -->|No| T6[request.dbSchema unset]
+ T5 --> T7{account.slug?}
+ T6 --> T7
+ T7 -->|Yes| T8[request.authEmailPrefix = id + _]
+ T7 -->|No| T9[No email prefix]
+ T8 --> T10[SuperTokens reset APIs use prefixed email]
+ T9 --> T10
+ end
+```
+
+## End-to-End Reset Sequence
+
+```mermaid
+sequenceDiagram
+ participant U as User / Browser
+ participant API as Fastify + ST middleware
+ participant ST as SuperTokens
+ participant Mail as Mailer
+
+ U->>API: POST generate reset token (email)
+ Note over API: generatePasswordResetTokenPOST copies
request.account, request.authEmailPrefix
+ API->>API: Prefix email field for ST if authEmailPrefix set
+ API->>ST: Create password reset token for prefixed email
+ ST-->>API: OK
+ API->>Mail: sendPasswordResetEmail (custom link + display email)
+ Note over Mail: Link host from appId / Referer / Origin / Hostname
Recipient: email with prefix stripped
+ Mail-->>U: Reset email
+
+ U->>API: POST reset password (token + new password)
+ Note over API: resetPasswordUsingToken uses request.account
and request.authEmailPrefix for getUserById context
+ API->>ST: Update password / consume token
+ ST-->>API: OK + userId
+ API->>Mail: Optional reset-password-notification email
+```
+
+## Detailed Steps
+
+### 1) Request reset token (`generatePasswordResetTokenPOST`)
+
+Source path: `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/generatePasswordResetTokenPost.ts`
+
+- Copies `input.userContext.account` and `input.userContext.authEmailPrefix` from the Fastify request (`input.options.req.original`).
+- Applies `updateFields` so the **`email` form field** is prefixed with `authEmailPrefix` when the tenant uses slug-based isolation (matches signup/signin behavior).
+- Delegates to SuperTokens to issue the token (stored in SuperTokens tables, not in `users`).
+
+### 2) Deliver email (`sendPasswordResetEmail`)
+
+Source path: `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/sendPasswordResetEmail.ts`
+
+- Rewrites SuperTokens’ default reset URL to a host derived from:
+ - `?appId=` (resolved to `config.apps`), or else
+ - `Referer` / `Origin` / `hostname`.
+- Sends the message to the **human-readable** address using `Email.removePrefix` with `userContext.authEmailPrefix`.
+
+### 3) Complete reset (`resetPasswordUsingToken`)
+
+Source path: `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/resetPasswordUsingToken.ts`
+
+- After SuperTokens reports `OK`, loads the user again with `getUserById` and passes through `request.account` and `request.authEmailPrefix` so **display email** matches other recipe overrides.
+- Sends a **“password changed”** notification email when configured (`resetPasswordNotification` templates / subjects in `fastify.config.user.emailOverrides`).
+
+### 4) `getUserById` display email
+
+Source path: `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/getUserById.ts`
+
+- Strips `authEmailPrefix` from emails returned to callers when a prefix is in context.
+
+## Multi-Database (`account.database`)
+
+- Tenant schema selection for **app tables** (`users`, `__account_users`, etc.) follows `request.dbSchema` / `account.database`, as in `user_creation_flow.md` and `runAccountMigrations`.
+- The **password reset token and password hash** remain in SuperTokens’ store; resetting a password does not migrate rows in `users` by itself.
+- Consistency matters: signup/signin and reset must agree on whether the SuperTokens email is **prefixed** (`authEmailPrefix`) for that account. Tenants resolved **by hostname** get that context on `/auth/*` routes; admin-app traffic does not.
+
+## Source File Index
+
+| Concern | Location |
+|--------|----------|
+| Account discovery, `dbSchema`, `authEmailPrefix` | `saas/packages/fastify/src/plugins/accountDiscoveryPlugin.ts` |
+| Main vs header vs hostname discovery | `saas/packages/fastify/src/lib/discoverAccount.ts` |
+| Default excluded routes (`/auth/`, etc.) | `saas/packages/fastify/src/config.ts` |
+| Reset token API override | `.../third-party-email-password/generatePasswordResetTokenPost.ts` |
+| Email delivery override | `.../third-party-email-password/sendPasswordResetEmail.ts` |
+| Consume token + notification | `.../third-party-email-password/resetPasswordUsingToken.ts` |
+| Recipe wiring | `saas/packages/fastify/src/supertokens/recipes/index.ts` |
+
+## Quick Verification Checklist
+
+- **Tenant user** (account host, slug): submit reset with unprefixed email in the form; SuperTokens receives prefixed email; email arrives unprefixed; completing reset succeeds when the browser/API uses the **same host** context as token generation.
+- **Admin user** (dedicated `saas.apps` domain): no tenant `account` on the request; SuperTokens email has **no** tenant prefix—matches how that user was provisioned.
+- **Multi-database**: after reset, sign-in still loads profile via `users` using the tenant schema implied by `account.database` during session creation (see `createNewSession` and sign-in recipes)—password change alone should not blank profile data.
diff --git a/packages/fastify/docs/user_creation_flow.md b/packages/fastify/docs/user_creation_flow.md
new file mode 100644
index 0000000..8212a46
--- /dev/null
+++ b/packages/fastify/docs/user_creation_flow.md
@@ -0,0 +1,167 @@
+# User Creation Flow
+
+This document explains how new users are created in this monorepo, with focus on `saas` and its dependency on `fastify/packages/user`.
+
+Assumption used here: the app user table is named `users`.
+
+## Components Involved
+
+- `saas/packages/fastify`: SaaS-specific signup/account logic
+- `fastify/packages/user`: base user persistence and SuperTokens integration
+- SuperTokens: authentication/session/role internals
+
+## Main Tables
+
+### App-managed tables
+
+- `users` (from `fastify/packages/user`)
+- `__accounts` (from `saas/packages/fastify`)
+- `__account_users` (from `saas/packages/fastify`)
+- `__account_invitations` (from `saas/packages/fastify`)
+
+### SuperTokens-managed tables
+
+- Auth/session tables (internal to SuperTokens)
+- Role mapping tables (for example `st__user_roles`)
+
+## `users` Schema Location (Public vs Tenant)
+
+- `users` is in `public` schema when account-level separate schema is not used.
+- `users` is in tenant schema when `account.database` is set (for example `s_xxxxxxxx`).
+- Runtime routing is done via `dbSchema` in request/user context, and tenant schema is prepared by `runAccountMigrations`.
+
+### Tenant Schema Diagram (`account.database` is set)
+
+```mermaid
+flowchart TD
+ A[Request resolved to account] --> B{account.database present?}
+ B -->|Yes| C[Set request.dbSchema = account.database]
+ C --> D[Use tenant search_path/schema]
+ D --> E[Create auth user in SuperTokens]
+ E --> F[Insert into tenant.users]
+ F --> G[Insert into tenant.__account_users]
+ G --> H{Invitation flow?}
+ H -->|Yes| I[Update tenant.__account_invitations.accepted_at]
+ H -->|No| J[Complete]
+```
+
+## High-Level Flow Diagram
+
+```mermaid
+flowchart TD
+ A[Signup request received] --> B{Signup type}
+
+ B -->|Email/password main app domain| C[Create account in __accounts]
+ C --> D[Create auth user in SuperTokens]
+ D --> E[Insert profile in users]
+ E --> F[Assign roles in SuperTokens role tables]
+ F --> G[Insert membership in __account_users as SAAS_ACCOUNT_OWNER]
+
+ B -->|Email/password existing account context| D2[Create auth user in SuperTokens]
+ D2 --> E2[Insert profile in users]
+ E2 --> F2[Assign roles in SuperTokens role tables]
+ F2 --> G2[Insert membership in __account_users as MEMBER or provided role]
+
+ B -->|Invitation signup token| H[Validate invitation in __account_invitations]
+ H --> D3[Create auth user in SuperTokens]
+ D3 --> E3[Insert profile in users]
+ E3 --> F3[Assign roles in SuperTokens role tables]
+ F3 --> G3[Insert membership in __account_users using invitation role]
+ G3 --> I[Update __account_invitations.accepted_at]
+
+ B -->|Third-party sign-in/up new user| J[Create auth user in SuperTokens]
+ J --> K[Insert profile in users]
+ K --> L[Assign roles in SuperTokens role tables]
+ L --> M{Account context exists?}
+ M -->|Yes| N[Insert membership in __account_users]
+ M -->|No| O[Finish]
+```
+
+## Detailed Flows
+
+### 1) Email/password signup from main app domain
+
+Source path:
+- `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/emailPasswordSignUpPost.ts`
+- `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/emailPasswordSignUp.ts`
+
+Writes:
+1. `__accounts` insert (new tenant/account)
+2. SuperTokens auth user creation
+3. `users` insert
+4. SuperTokens role assignment insert(s)
+5. `__account_users` insert as `SAAS_ACCOUNT_OWNER`
+
+Failure handling:
+- If signup API result is not OK, created account is deleted.
+- If `users` insert fails, SuperTokens user is deleted.
+
+### 2) Email/password signup on existing account domain/subdomain
+
+Source path:
+- `saas/packages/fastify/src/plugins/accountDiscoveryPlugin.ts`
+- `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/emailPasswordSignUp.ts`
+
+Writes:
+1. SuperTokens auth user creation
+2. `users` insert
+3. SuperTokens role assignment insert(s)
+4. `__account_users` insert (default member role unless overridden)
+
+### 3) Invitation signup (new user)
+
+Source path:
+- `saas/packages/fastify/src/model/accountInvitations/handlers/signup.ts`
+
+Writes:
+1. SuperTokens auth user creation
+2. `users` insert
+3. SuperTokens role assignment insert(s)
+4. `__account_users` insert using invitation role
+5. `__account_invitations.accepted_at` update
+
+### 4) Invitation join (existing logged-in user)
+
+Source path:
+- `saas/packages/fastify/src/model/accountInvitations/handlers/join.ts`
+
+Writes:
+1. `__account_users` insert
+2. `__account_invitations.accepted_at` update
+
+No new row is created in `users` in this path.
+
+### 5) Third-party signup (new social user)
+
+Source path:
+- `saas/packages/fastify/src/supertokens/recipes/third-party-email-password/thirdPartySignInUp.ts`
+
+For new users (`createdNewUser = true`), writes:
+1. SuperTokens auth user creation
+2. `users` insert
+3. SuperTokens role assignment insert(s)
+4. optional `__account_users` insert (if account context exists)
+
+For existing users (`createdNewUser = false`):
+- no new user rows; `users.last_login_at` is updated.
+
+## Multi-Database Note
+
+If an account has its own schema (`account.database`), the same logical writes happen in that schema context for:
+- `users`
+- `__account_users`
+- `__account_invitations`
+
+If `account.database` is not set, these writes go to `public` schema.
+
+This is wired via request context (`dbSchema`) and account migrations in:
+- `saas/packages/fastify/src/migrations/runAccountMigrations.ts`
+
+## Quick Verification Checklist
+
+When a brand-new user signs up for a new account, verify inserts in:
+- SuperTokens auth table(s)
+- `users`
+- SuperTokens role mapping table(s)
+- `__account_users`
+- `__accounts` (main app self-signup path only)