# oryzon/orysaas architecture

> Architecture diagram of the GitHub repository oryzon/orysaas, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/oryzon/orysaas
- Repository: https://github.com/oryzon/orysaas

## Overview

OrySaaS is a multi-tenant SaaS starter with a Nuxt frontend and Express/TypeORM API. The principal flow is a user operating the portal: frontend pages and composables call API controllers, which enforce authentication/tenant rules and persist domain records. Major capabilities also include CMS, billing and quota management, notifications, scheduled jobs, uploads, and email. Edges are limited to README-documented or indexed/source-visible relationships; many individual controllers and frontend call sites were not sampled.

Main entry points: [`core/app.ts`](https://github.com/oryzon/orysaas/blob/main/core/app.ts) (API bootstrap), [`core/config/datasource.ts`](https://github.com/oryzon/orysaas/blob/main/core/config/datasource.ts) (MariaDB connection), [`core/controllers/api/auth/auth.controller.ts`](https://github.com/oryzon/orysaas/blob/main/core/controllers/api/auth/auth.controller.ts) (Authentication), [`core/controllers/api/user/user.controller.ts`](https://github.com/oryzon/orysaas/blob/main/core/controllers/api/user/user.controller.ts) (User profile)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Web frontend"]
  node_portal["Portal pages"]
  node_public_pages["Public pages"]
  node_api_client["API client<br/>[useApi.ts]"]
  node_auth_ui["Authentication UI<br/>[useAuth.ts]"]
end

subgraph group_api["API runtime"]
  node_app_boot["API bootstrap<br/>[app.ts]"]
  node_controllers["Controller routing<br/>[controller.ts]"]
  node_decorators["Route &amp; access decorators<br/>[index.ts]"]
end

subgraph group_domain["SaaS capabilities"]
  node_auth["Authentication<br/>[auth.controller.ts]"]
  node_account["User profile<br/>[user.controller.ts]"]
  node_organizations["Organizations"]
  node_membership["Membership &amp; roles"]
  node_cms["CMS pages &amp; blocks<br/>[page.controller.ts]"]
  node_billing["Plans &amp; billing<br/>[stripe.helper.ts]"]
  node_quotas["Quota enforcement<br/>[check-quota.ts]"]
  node_notifications["Notifications"]
  node_jobs["Scheduled jobs<br/>[runner.ts]"]
  node_uploads["Logo uploads"]
  node_mail["Transactional email<br/>[mail.service.ts]"]
  node_stripe_webhook["Stripe webhook<br/>[stripe.webhook.ts]"]
  node_sse["SSE stream<br/>[sse.service.ts]"]
end

subgraph group_storage["Persistence"]
  node_data_source[("MariaDB connection<br/>[datasource.ts]")]
  node_user_store[("User records<br/>[user.repository.ts]")]
  node_token_store[("Token records")]
  node_org_store[("Organization records")]
  node_membership_store[("Membership records")]
  node_plan_store[("Plan records<br/>[plan.repository.ts]")]
  node_notification_store[("Notification records")]
end

node_user(("SaaS user"))
node_mail_service["SMTP service"]
node_stripe["Stripe"]

node_user -->|"uses"| node_portal
node_user -->|"visits"| node_public_pages
node_portal -->|"requests API"| node_api_client
node_public_pages -->|"requests API"| node_api_client
node_auth_ui -.->|"uses"| node_api_client
node_api_client -->|"calls API"| node_app_boot
node_app_boot -->|"initializes"| node_data_source
node_app_boot -->|"loads routes"| node_controllers
node_app_boot -->|"starts"| node_jobs
node_app_boot -->|"registers"| node_stripe_webhook
node_controllers -.->|"routes to"| node_auth
node_auth -->|"uses"| node_decorators
node_auth -->|"reads/writes"| node_user_store
node_auth -->|"reads/writes"| node_token_store
node_auth -->|"sends email"| node_mail
node_account -->|"reads/writes"| node_user_store
node_account -->|"checks/updates"| node_membership_store
node_account -->|"updates"| node_org_store
node_account -->|"cancels subscription"| node_billing
node_billing -->|"reads plans"| node_plan_store
node_stripe_webhook -->|"syncs billing"| node_billing
node_stripe_webhook -->|"verifies events"| node_stripe
node_membership -->|"queries organizations"| node_org_store
node_app_boot -.->|"routes via controllers"| node_cms
node_cms -.->|"persists content"| node_data_source
node_app_boot -.->|"registers enforcement"| node_quotas
node_notifications -->|"persists"| node_notification_store
node_notifications -->|"publishes events"| node_sse
node_jobs -->|"loads job state"| node_data_source
node_uploads -.->|"serves uploaded files"| node_app_boot
node_mail -->|"sends through"| node_mail_service
node_data_source -->|"backs"| node_user_store
node_data_source -->|"backs"| node_token_store
node_data_source -->|"backs"| node_org_store
node_data_source -->|"backs"| node_membership_store
node_data_source -->|"backs"| node_plan_store

click node_portal "https://github.com/oryzon/orysaas/tree/main/webapp/app/pages/portal"
click node_public_pages "https://github.com/oryzon/orysaas/tree/main/webapp/app/pages"
click node_api_client "https://github.com/oryzon/orysaas/blob/main/webapp/app/composables/useApi.ts"
click node_auth_ui "https://github.com/oryzon/orysaas/blob/main/webapp/app/composables/useAuth.ts"
click node_app_boot "https://github.com/oryzon/orysaas/blob/main/core/app.ts"
click node_auth "https://github.com/oryzon/orysaas/blob/main/core/controllers/api/auth/auth.controller.ts"
click node_account "https://github.com/oryzon/orysaas/blob/main/core/controllers/api/user/user.controller.ts"
click node_organizations "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization.repository.ts"
click node_membership "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization-member.repository.ts"
click node_cms "https://github.com/oryzon/orysaas/blob/main/core/controllers/api/pages/page.controller.ts"
click node_billing "https://github.com/oryzon/orysaas/blob/main/core/helpers/stripe.helper.ts"
click node_quotas "https://github.com/oryzon/orysaas/blob/main/core/decorators/check-quota.ts"
click node_notifications "https://github.com/oryzon/orysaas/blob/main/core/services/notification.service.ts"
click node_jobs "https://github.com/oryzon/orysaas/blob/main/core/jobs/runner.ts"
click node_uploads "https://github.com/oryzon/orysaas/blob/main/core/services/organization-logo.service.ts"
click node_mail "https://github.com/oryzon/orysaas/blob/main/core/services/mail.service.ts"
click node_stripe_webhook "https://github.com/oryzon/orysaas/blob/main/core/webhooks/stripe.webhook.ts"
click node_controllers "https://github.com/oryzon/orysaas/blob/main/core/controllers/controller.ts"
click node_decorators "https://github.com/oryzon/orysaas/blob/main/core/decorators/index.ts"
click node_data_source "https://github.com/oryzon/orysaas/blob/main/core/config/datasource.ts"
click node_user_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/user.repository.ts"
click node_token_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/token.repository.ts"
click node_org_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization.repository.ts"
click node_membership_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization-member.repository.ts"
click node_plan_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/plan.repository.ts"
click node_notification_store "https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/notification.repository.ts"
click node_sse "https://github.com/oryzon/orysaas/blob/main/core/services/sse.service.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_portal,node_public_pages,node_api_client,node_auth_ui,node_user toneBlue
class node_app_boot,node_controllers,node_decorators toneAmber
class node_auth,node_account,node_organizations,node_membership,node_cms,node_billing,node_quotas,node_notifications,node_jobs,node_uploads,node_mail,node_stripe_webhook,node_sse toneMint
class node_data_source,node_user_store,node_token_store,node_org_store,node_membership_store,node_plan_store,node_notification_store toneRose
class node_mail_service,node_stripe toneIndigo
```

## Components

### Web frontend

- [Portal pages](https://github.com/oryzon/orysaas/tree/main/webapp/app/pages/portal): `webapp/app/pages/portal`
- [Public pages](https://github.com/oryzon/orysaas/tree/main/webapp/app/pages): `webapp/app/pages`
- [API client](https://github.com/oryzon/orysaas/blob/main/webapp/app/composables/useApi.ts): `webapp/app/composables/useApi.ts`
- [Authentication UI](https://github.com/oryzon/orysaas/blob/main/webapp/app/composables/useAuth.ts): `webapp/app/composables/useAuth.ts`

### API runtime

- [API bootstrap](https://github.com/oryzon/orysaas/blob/main/core/app.ts): `core/app.ts`
- [Controller routing](https://github.com/oryzon/orysaas/blob/main/core/controllers/controller.ts): `core/controllers/controller.ts`
- [Route & access decorators](https://github.com/oryzon/orysaas/blob/main/core/decorators/index.ts): `core/decorators/index.ts`

### SaaS capabilities

- [Authentication](https://github.com/oryzon/orysaas/blob/main/core/controllers/api/auth/auth.controller.ts): `core/controllers/api/auth/auth.controller.ts`
- [User profile](https://github.com/oryzon/orysaas/blob/main/core/controllers/api/user/user.controller.ts): `core/controllers/api/user/user.controller.ts`
- [Organizations](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization.repository.ts): `core/databases/repositories/organization.repository.ts`
- [Membership & roles](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization-member.repository.ts): `core/databases/repositories/organization-member.repository.ts`
- [CMS pages & blocks](https://github.com/oryzon/orysaas/blob/main/core/controllers/api/pages/page.controller.ts): `core/controllers/api/pages/page.controller.ts`
- [Plans & billing](https://github.com/oryzon/orysaas/blob/main/core/helpers/stripe.helper.ts): `core/helpers/stripe.helper.ts`
- [Quota enforcement](https://github.com/oryzon/orysaas/blob/main/core/decorators/check-quota.ts): `core/decorators/check-quota.ts`
- [Notifications](https://github.com/oryzon/orysaas/blob/main/core/services/notification.service.ts): `core/services/notification.service.ts`
- [Scheduled jobs](https://github.com/oryzon/orysaas/blob/main/core/jobs/runner.ts): `core/jobs/runner.ts`
- [Logo uploads](https://github.com/oryzon/orysaas/blob/main/core/services/organization-logo.service.ts): `core/services/organization-logo.service.ts`
- [Transactional email](https://github.com/oryzon/orysaas/blob/main/core/services/mail.service.ts): `core/services/mail.service.ts`
- [Stripe webhook](https://github.com/oryzon/orysaas/blob/main/core/webhooks/stripe.webhook.ts): `core/webhooks/stripe.webhook.ts`
- [SSE stream](https://github.com/oryzon/orysaas/blob/main/core/services/sse.service.ts): `core/services/sse.service.ts`

### Persistence

- [MariaDB connection](https://github.com/oryzon/orysaas/blob/main/core/config/datasource.ts): `core/config/datasource.ts`
- [User records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/user.repository.ts): `core/databases/repositories/user.repository.ts`
- [Token records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/token.repository.ts): `core/databases/repositories/token.repository.ts`
- [Organization records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization.repository.ts): `core/databases/repositories/organization.repository.ts`
- [Membership records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/organization-member.repository.ts): `core/databases/repositories/organization-member.repository.ts`
- [Plan records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/plan.repository.ts): `core/databases/repositories/plan.repository.ts`
- [Notification records](https://github.com/oryzon/orysaas/blob/main/core/databases/repositories/notification.repository.ts): `core/databases/repositories/notification.repository.ts`

### Other components

- **SaaS user**
- **SMTP service**
- **Stripe**

## Connections

- SaaS user → Portal pages: uses (evidence: `README.md`)
- SaaS user → Public pages: visits (evidence: `README.md`)
- Portal pages → API client: requests API (evidence: `README.md`)
- Public pages → API client: requests API (evidence: `README.md`)
- Authentication UI → API client: uses
- API client → API bootstrap: calls API (evidence: `README.md`)
- API bootstrap → MariaDB connection: initializes (evidence: `core/app.ts`)
- API bootstrap → Controller routing: loads routes (evidence: `core/app.ts`)
- API bootstrap → Scheduled jobs: starts (evidence: `core/app.ts`)
- API bootstrap → Stripe webhook: registers (evidence: `core/app.ts`)
- Controller routing → Authentication: routes to
- Authentication → Route & access decorators: uses (evidence: `core/controllers/api/auth/auth.controller.ts`)
- Authentication → User records: reads/writes (evidence: `core/controllers/api/auth/auth.controller.ts`)
- Authentication → Token records: reads/writes (evidence: `core/controllers/api/auth/auth.controller.ts`)
- Authentication → Transactional email: sends email (evidence: `core/controllers/api/auth/auth.controller.ts`)
- User profile → User records: reads/writes (evidence: `core/controllers/api/user/user.controller.ts`)
- User profile → Membership records: checks/updates (evidence: `core/controllers/api/user/user.controller.ts`)
- User profile → Organization records: updates (evidence: `core/controllers/api/user/user.controller.ts`)
- User profile → Plans & billing: cancels subscription (evidence: `core/controllers/api/user/user.controller.ts`)
- Plans & billing → Plan records: reads plans (evidence: `core/helpers/stripe.helper.ts`)
- Stripe webhook → Plans & billing: syncs billing (evidence: `core/webhooks/stripe.webhook.ts`)
- Stripe webhook → Stripe: verifies events (evidence: `core/webhooks/stripe.webhook.ts`)
- Membership & roles → Organization records: queries organizations (evidence: `core/databases/repositories/organization-member.repository.ts`)
- API bootstrap → CMS pages & blocks: routes via controllers
- CMS pages & blocks → MariaDB connection: persists content
- API bootstrap → Quota enforcement: registers enforcement
- Notifications → Notification records: persists (evidence: `core/services/notification.service.ts`)
- Notifications → SSE stream: publishes events (evidence: `core/services/notification.service.ts`)
- Scheduled jobs → MariaDB connection: loads job state (evidence: `core/jobs/runner.ts`)
- Logo uploads → API bootstrap: serves uploaded files
- Transactional email → SMTP service: sends through (evidence: `core/services/mail.service.ts`)
- MariaDB connection → User records: backs (evidence: `core/databases/repositories/user.repository.ts`)
- MariaDB connection → Token records: backs (evidence: `core/databases/repositories/token.repository.ts`)
- MariaDB connection → Organization records: backs (evidence: `core/databases/repositories/organization.repository.ts`)
- MariaDB connection → Membership records: backs (evidence: `core/databases/repositories/organization-member.repository.ts`)
- MariaDB connection → Plan records: backs (evidence: `core/databases/repositories/plan.repository.ts`)
