Modular Monolith SAAS Starter

Use cases

  • Base solution for a medium - large saas
  • github style user / organsation model but with projects instead of repo's
  • modular in nature to allow additional feature domains

Tech Stack

  • modular monolith
  • choose boring technologies
    • postgres
    • ef/dapper
    • razor pages
    • htmx
    • transactional outbox

Modules

Users Module

  • ✌️ Users can register
  • ✌️ Users can login
  • ✌️ Users can reset password
  • ✌️ Users can update name
  • ✌️ Users can update password
  • ✌️ Users can create ApiKey
  • ✌️ Users can list ApiKeys
  • ✌️ Users can revoke ApiKeys
  • ✌️ Users can authenticate with ApiKey

Tenants Module

  • ✌️ Users can create organisations
  • ✌️ Users can be organisation administrators
  • ✌️ Users can operate within an organisation's context
  • ✌️ Users can add and remove members
  • ✌️ Users can promote and demote members
  • ✌️ Users can delete organisations
  • ✌️ Users can create invitations
  • ❌ Users can accept invitations and become members
  • ❌ Users can reject invitations
  • ✌️ Users can create projects
  • ✌️ Users can operate within an projects's context
  • ❓ Should projects be moved to their own modules?
  • ❓ Should invitiations be moved out to its own module too?

Translations Module

  • ✌️ Users can create terms
  • ✌️ Users can update terms
  • ✌️ Users can delete terms
  • ✌️ Users can add languages
  • ✌️ Users can add translations of a term to a language
  • ✌️ Users can update translations of a term to a language
  • ✌️ Users can import terms
  • ✌️ Users can import translations
  • ✌️ Users can generate statistics on terms/translations
  • ✌️ Users can export to RESX files
  • ✌️ Users can export to CSV files
  • ✌️ Route to this via a 'Project scoped module' route
  • ❓ Rename to 'Localisation' module

System Considerations

  • ✌️ Modules are well isolated, communicate via integration events
  • ✌️ Modules contain complete functionality, razor pages / api endpoints included.
  • ✌️ Use transactional outbox for publishing events
  • ✌️ Publish integration events via transactional outbox
  • ✌️ Publish queued commands via transactional outbox
  • ✌️ In memory publishing of events between each module's outbox and another's inbox
  • ❌ AWS SQS for outbox/inbox (https://github.com/awslabs/aws-dotnet-messaging or similar)
  • ✌️ Distinct container instance and composition root foreach module
  • ❌ Security at the postgres connection level via connection context being set

Conventions

As the razor pages co-habitate in the web host a convention is needed to ensure the routes are globally unique. :question: Perhaps modules could defined user, org and project scoped functionality?

  • User Scoped modules

    • 💻 /users/{user}/{module}/{path}
    • 💻 /users/peter/tasks/list
  • Org Scoped modules

    • 💻 /orgs/{org}/{module}/{path}
    • 💻 /ogs/microsoft/invitations/list
  • Project Scoped modules

    • 💻 /orgs/{org}/projects/{project}/{module}/{path}
    • 💻 /ogs/microsoft/projects/landing-page/localisation/terms/list
    • 💻 /ogs/microsoft/projects/landing-page/localisation/translations/en-au/list

Acceptance Tests

  • ✌️ Added PageIds to identify the current page
  • ✌️ Organisation Selector Tests
  • ✌️ Project Selector Tests
  • ❌ User Menu Tests
  • ✌️ Basic user flow Tests
  • Logs impersonation links for easier manual retesting of scenarios

Other

Context

  • Endpoint
    • Endpoint provides a context accessor for modules to retreive the context of a command or query
    • Context is retrieved via route parameters and authentication details
dotnet ef dbcontext scaffold "Username=admin;Password=password;Database=db;Host=localhost;Port=5432;Search Path=translate;Include Error Detail=true;Log Parameters=true" \
  Npgsql.EntityFrameworkCore.PostgreSQL \
  -o Infrastructure/temp \
  -c "Db"

todo:

  • remove all schema prefixes from application layer
  • remove all ef queries from application layer
  • look into SqlMapper.AddTypeHandler(LanguageIdTypeHandler.Default);

Saas Ideas

  • Monitoring
    • Check HTTP Endpoint health
    • Check IP Address health
    • Check DNS resolution
  • Image resizing
    • Thumbnail generation
  • PDF generation
    • HTML to PDF
    • URL to PDF
  • Feature switches
    • Manual
    • User based
    • Time based
    • Percentage based
    • Random
  • Content Management
    • Data Types
    • Tags
    • Search / List / Filter
  • Organisation Invitations
  • Project Invitations
  • Notifications (Email, SMS, Push)
  • Analytics
  • Metrics
    • Counters
    • Gauges
    • Timers
    • Embeddable via URL / Iframe
  • Security
    • User permissions
    • User role
    • User groups