Executable roadmap. Phases, checklists, recorded decisions, risks. Updated as deliveries progress. Items are small enough to become an isolated PR.
Build Luga ModuleManager — Brazilian B2B multi-product SaaS platform for SMBs — in incremental phases, starting with a solid foundation and ending the MVP with 3 sellable modules (Core + Customers + Payments).
Guiding principle: each phase has a testable, deployable, demonstrable deliverable. No "invisible foundation for 3 months". Even Phase 0 ends with something deployed to staging.
| # | Decision | Rationale | Status |
|---|---|---|---|
| 001 | Modular Monolith Extractable | Integrated Suite with monolith simplicity + future microservices option | ✅ |
| 002 | Suite (not Federation) | SMB ICP requires cohesive UX; shared core entities | ✅ |
| 003 | .NET 10 + ASP.NET Core 10 + EF Core 10 | Latest LTS stack, performance, Microsoft tooling | ✅ |
| 004 | Azure SQL Database Serverless | 100% Microsoft stack, auto-pause saves on MVP | ✅ |
| 005 | Microsoft Entra External ID (single tenant + tenant_id claim) | Microsoft stack, scales for SMBs, low cost | ✅ |
| 006 | Azure Container Apps + GHCR public | Scale-to-zero, low cost, aligned with future extraction | ✅ |
| 007 | GitHub Actions with OIDC | No secrets, modern standard | ✅ |
| 008 | Bicep for IaC | Native Azure, simple, no state | ✅ |
| 009 | Controllers (not Minimal APIs) | Developer decision — more conventional | ✅ |
| 010 | MediatR (not Mediator source-gen) | Huge community, better for Visual Studio | ✅ |
| 011 | Mapperly (not AutoMapper) | Source-gen, no reflection, explicit | ✅ |
| 012 | Repository Pattern with generic base | Developer decision — wrapper over EF | ✅ |
| 013 | EF Core Interceptors (not override) | Composable, testable, modern Microsoft pattern | ✅ |
| 014 | LugaDbContextBase in BuildingBlocks.Infrastructure | Reuse without violating cross-module architecture | ✅ |
| 015 | Schema per module on SQL Server | Physical isolation, prepares for extraction | ✅ |
| 016 | Outbox per module | Each module takes its outbox when extracted | ✅ |
| 017 | Custom Result | No exception for business flow | ✅ |
| 018 | TimeProvider for testable time | .NET 8+ standard | ✅ |
| 019 | Customer in Customers module (not core) | Rich entity, evolves a lot, isolates for extraction | ✅ |
| 020 | Visual Studio 2022 17.12+ | Developer decision | ✅ |
| 021 | Mailtrap for transactional email | Generous free tier | ✅ |
| 022 | Manual WhatsApp via wa.me in MVP | Free, no onboarding | ✅ |
| 023 | Asaas as primary gateway (V2 covered) | BR focus, immediate Pix, competitive fees | ✅ |
| 024 | Own billing via Stripe/Asaas/Mercado Pago | No dogfooding in MVP | ✅ |
| 025 | Frontend: Nx monorepo + Next.js 15 + React 19 | Modern standard, strong AI tooling | ✅ |
| 026 | Single web app with 3 areas (marketing/dashboard/admin) | Integrated UX, simple for MVP | ✅ |
| 027 | Mobile via Expo + React Native in V1.1+ | Logic reuse via shared packages | ✅ |
| 028 | PWA enabled from Phase 0 | Basic mobile at no extra cost | ✅ |
| 029 | Subdomains: luga.com / app.luga.com / api.luga.com | Clear context separation | ✅ |
| 030 | Custom fields as JSON column | Performant on SQL Server, queries via JSON_VALUE | ✅ |
| Topic | When to decide |
|---|---|
| Exact plan pricing (Starter / Pro / Business) | Close to launch, based on validation |
| Chosen gateway to charge own tenants | Phase 1 start (Stripe / Asaas / Mercado Pago) |
| Feature flags tooling | V2, when justified |
| Backup and DR policy | Before production (end of Phase 1) |
| Detailed LGPD compliance (DPO, exclusion flow) | Before public launch |
| Customer support (Intercom, Crisp, custom) | Before public launch |
| Product analytics (PostHog, Mixpanel) | V1.1+ |
| Status page (Statuspage.io, Instatus) | V1.1+ |
| Terms of use and privacy policy | Before public launch |
| Automated WhatsApp (Z-API vs Cloud API) | V2 |
| Mobile apps (iOS + Android) | V1.1+ |
To avoid scope creep, EXPLICITLY not in MVP:
- ❌ Documents module (DMS) — V2
- ❌ Signatures module — V2
- ❌ Dedicated CRM module — V3
- ❌ NF module (NFS-e) — V3
- ❌ End customer portal — V4
- ❌ Unified messaging (Talk) — V4
- ❌ Scheduling — V5
- ❌ Financial/Income statement — V5
- ❌ Native mobile app — V1.1+
- ❌ Actions engine (generic automation) — V2
- ❌ Automated WhatsApp via API — V2
- ❌ Stripe Connect (international billing) — V2
- ❌ Multi-gateway in Payments (only Manual + Asaas in MVP) — V2 adds Pagar.me/MP
- ❌ Full white-label (per-tenant colors/brand) — V3
- ❌ Public Luga webhooks for external systems — V2 (with Actions)
- ❌ Public API for external devs — V3
- ❌ Extension marketplace — V3+
Goal: build complete technical foundation supporting all future modules, with infrastructure deployed to staging. No business features yet — just plumbing.
Definition of done: base API runs on staging Container App, authenticates via Entra External ID, persists to Azure SQL, frontend runs on localhost showing functional login.
Estimate: 4-6 weeks (solo dev) / 2-3 weeks (with pair).
- (S) Create
luga-ModuleManagerrepo on GitHub (private initially) - (S)
.gitignorefor .NET + Node + Visual Studio + Rider - (S)
.editorconfigconfigured for Visual Studio + StyleCop - (S) Initial
README.mdwith description and how to run locally - (S) Copy
CLAUDE.mdandPLAN.mdto repo root - (S) Set branch protection rules on
main(require PR, require CI)
- (S) Create
backend/Luga.ModuleManager.sln - (S)
Directory.Build.props(Nullable, ImplicitUsings, LangVersion, TreatWarningsAsErrors) - (S)
Directory.Packages.props(Central Package Management) - (S)
global.json(SDK pinned to 10.0.x) - (M) Create BuildingBlocks projects:
-
Luga.BuildingBlocks.Domain -
Luga.BuildingBlocks.Application -
Luga.BuildingBlocks.Infrastructure -
Luga.BuildingBlocks.IntegrationEvents
-
- (M) Create Core module projects:
-
Luga.Modules.Core.Domain -
Luga.Modules.Core.Application -
Luga.Modules.Core.Infrastructure -
Luga.Modules.Core.Api -
Luga.Modules.Core.Contracts
-
- (S) Create
Luga.Bootstrapper.Api - (S) Configure project references following the rules
- (S) Create test projects (Architecture, BuildingBlocks, Modules.Core)
- (S)
IDomainEvent.csinterface - (S)
IIntegrationEvent.csinterface (in IntegrationEvents) - (M) Marker interfaces:
-
IAuditable.cs -
ISoftDeletable.cs -
IMultiTenant.cs -
IConcurrencyAware.cs -
IActivatable.cs -
IHasDomainEvents.cs
-
- (M) Entity hierarchy:
-
EntityBase.cs -
AuditableEntity.cs -
FullAuditableEntity.cs -
TenantEntity.cs
-
- (M) Result pattern:
-
Result.cs -
Result{T}.cs -
Error.cs -
GeneralErrors.cs(NotFound, Validation, Conflict, Unauthorized)
-
- (S) Unit tests for Result and GeneralErrors
- (S)
ITenantContext.csinterface - (S)
ICurrentUser.csinterface (UserId + Username) - (S)
IUnitOfWork.csinterface - (M)
IRepository<T>.csbase interface - (S)
PagedList<T>.cs+PagedRequest.cs - (M) MediatR pipeline behaviors:
-
LoggingBehavior.cs -
ValidationBehavior.cs -
IdempotencyBehavior.cs -
PerformanceBehavior.cs
-
- (S)
ResultExtensions.cs(ToActionResult)
- (M)
LugaDbContextBase.cs(global query filters, concurrency tokens) - (L) Interceptors:
-
AuditableEntityInterceptor.cs -
TenantIdInterceptor.cs -
SoftDeleteInterceptor.cs -
ActivationTrackingInterceptor.cs -
DomainEventToOutboxInterceptor.cs
-
- (M) Outbox pattern:
-
OutboxMessage.cs -
OutboxMessageConfiguration.cs(base) -
IOutboxProcessor.cs -
OutboxProcessor.cs(Hangfire job)
-
- (M) Repository base:
-
Repository<T>.csgeneric implementation -
SpecificationEvaluator.cs(Ardalis.Specification)
-
- (M) Tenancy:
-
TenantContext.cs -
TenantContextMiddleware.cs -
TenantClaimsExtractor.cs
-
- (M) Auth:
-
EntraExternalIdConfiguration.cs -
JwtBearerSetup.cs -
CurrentUserAccessor.cs
-
- (M) Idempotency:
-
IdempotencyKey.csentity -
IdempotencyStore.cs -
IdempotencyMiddleware.cs
-
- (S) Hangfire setup (
HangfireSetup.cs, dashboard auth filter) - (M) Observability:
-
SerilogSetup.cs -
OpenTelemetrySetup.cs -
HealthChecksSetup.cs
-
- (S) Events:
-
InProcessIntegrationEventBus.cs -
DomainEventDispatcher.cs
-
- (S)
PersistenceServiceCollectionExtensions.cs(registers interceptors)
- (M) Domain:
-
Tenant.cs(FullAuditableEntity, NOT IMultiTenant) -
TenantUser.cs(TenantEntity) -
TenantStatus.csenum -
TenantUserRole.csenum - Domain events (TenantCreated, etc.)
- Errors (TenantErrors, TenantUserErrors)
-
- (M) Contracts:
-
ITenantsService.cs -
IUsersService.cs - DTOs
- Integration events (TenantCreatedIntegrationEvent)
-
- (M) Application — minimal features:
-
RegisterTenantCommand+ Handler + Validator (public signup) -
GetCurrentTenantQuery+ Handler -
GetMyProfileQuery+ Handler - Mappers (Mapperly)
- Repositories (
ITenantRepository,ITenantUserRepository)
-
- (M) Infrastructure:
-
CoreDbContext.cs(extends LugaDbContextBase) - EF Core configurations
- Concrete repositories
-
TenantsService.cs(impl ITenantsService) -
UsersService.cs(impl IUsersService) - Initial migration (
Initial) -
CoreModule.cs(composition root)
-
- (M) Api:
-
TenantsController(POST /api/tenants/register, GET /api/tenants/me) -
UsersController(GET /api/users/me) -
CoreApiModule.cs
-
- (M) Custom claims provider endpoint (POST /api/auth/enrich-claims) called by Entra
- (M)
Program.cswith:- BuildingBlocks setup
- Entra External ID auth
- Tenancy middleware
- Observability (Serilog + OpenTelemetry)
- MediatR + behaviors
- CoreModule
- Hangfire dashboard (
/jobs) - Health checks (
/health/live,/health/ready) - OpenAPI (Scalar UI)
- (S)
appsettings.json+appsettings.Development.json - (S)
Dockerfileto containerize API - (S)
.dockerignore
- (M)
Luga.AppHostproject - (M) Compose: SQL Server (container) + API + Hangfire dashboard
- (S) Document in README how to run (
dotnet run --project src/AppHost)
- (M)
Luga.Tests.Architecture:- ArchUnitNET tests for dependency rules
- Domain doesn't depend on EF Core
- Modules don't reference internals of other modules
- Application doesn't depend on Infrastructure
- Contracts doesn't depend on Domain of other modules
- Naming conventions (Handler, Command, Query suffixes)
- (M) Test base classes:
-
IntegrationTestBasewith Testcontainers (SQL Server) - Custom
WebApplicationFactoryFixture - FakeTimeProvider helper
-
- (S) Smoke test: POST /api/tenants/register creates tenant and returns 201
- (S) Initialize Nx workspace in
frontend/ - (S)
pnpm-workspace.yamlat repo root - (M) Create
apps/web(Next.js 15, App Router, TypeScript) - (M) Configure Tailwind v4 + shadcn/ui
- (M) Create libs:
-
libs/ui(shadcn base components) -
libs/api-client(placeholder, openapi-generator config) -
libs/auth(MSAL config) -
libs/i18n(PT-BR setup with next-intl) -
libs/shared/utils -
libs/shared/types
-
- (S) Configure Nx tags for module boundaries
- (M) Setup MSAL with Entra External ID (functional login)
- (M) Base layout with 3 areas: (marketing), (dashboard), (admin)
- (S) Functional login page integrated with API
- (S) PWA enabled (
@ducanh2912/next-pwa) - (S) Manifest + PWA icons
- (L)
infra/main.biceporchestrator - (M) Modules:
-
containerapp.bicep(Container App + Container Apps Environment) -
sqldatabase.bicep(Azure SQL Server + Database Serverless) -
keyvault.bicep -
storage.bicep(Blob Storage) -
appinsights.bicep(App Insights + Log Analytics) -
entra.bicep(External ID tenant reference — usually manual via portal)
-
- (S)
parameters/staging.bicepparam - (S)
parameters/production.bicepparam - (M) Initial manual deploy (create resource group, run bicep)
- (M) Configure Managed Identity for Container App to access Key Vault and SQL
- (M)
.github/workflows/ci-backend.yml:- Runs on PRs touching
backend/** - dotnet restore, build, test (unit + integration via Testcontainers)
- Architecture tests
- dotnet format --verify-no-changes
- Runs on PRs touching
- (M)
.github/workflows/ci-frontend.yml:- Runs on PRs touching
frontend/** - pnpm install, lint, test, build (Nx affected)
- Runs on PRs touching
- (M)
.github/workflows/ci-infra.yml:- Runs on PRs touching
infra/** - az deployment what-if (preview changes)
- Runs on PRs touching
- (M)
.github/workflows/deploy-staging.yml:- Push on main: build Docker image, push to GHCR
- Auto deploy to staging Container App
- Apply migrations (dedicated job)
- (M)
.github/workflows/deploy-production.yml:- workflow_dispatch with version input
- Manual deploy with approval (environment protection rule)
- (M) Configure OIDC between GitHub Actions and Azure (Federated Identity Credential)
- (S) Document deploy in README
- ✅ API runs locally via
dotnet run --project src/AppHost - ✅ Login works via MSAL → Entra External ID → API validates JWT
- ✅ POST /api/tenants/register creates tenant and populates JWT with
tenant_id - ✅ GET /api/users/me returns logged user data with correct tenant_id
- ✅ ArchUnitNET passes in CI
- ✅ Integration tests pass in CI (Testcontainers)
- ✅ Auto deploy to staging when merging to main
- ✅ Next.js frontend running on localhost showing login + dashboard placeholder
- ✅ Hangfire dashboard accessible at
/jobs(authenticated) - ✅ Application Insights receiving logs and metrics
Goal: sellable product. Tenant can sign up, choose a plan, manage customers, configure billing plans, manually mark payments OR integrate with Asaas, and send billing notifications.
Definition of done: 1-3 beta tenants using in production, processing real charges.
Estimate: 8-12 weeks (after Phase 0).
- (M) Domain entities:
-
SubscriptionPlan.cs(FullAuditableEntity) -
PlanItem.cs(item inside bundle) -
ModuleTier.cs(tier catalog per module) -
TenantSubscription.cs(TenantEntity) - Enums: BillingCycle (Monthly, Yearly), SubscriptionStatus
-
- (M) Application features:
-
CreatePlanCommand(admin only) -
UpdatePlanCommand(admin only) -
ListPlansQuery(public — for institutional landing) -
SubscribeTenantToPlanCommand -
GetCurrentSubscriptionQuery -
CheckModuleAccessQuery(verifies tenant has module X active)
-
- (M) Infrastructure:
- Repositories
- Migration with seeds of initial plans (Free, Starter, Pro, Business)
- (M) API Controllers
- (M) Frontend admin: catalog management UI (CRUD plans, tiers, bundles)
- (M) Frontend marketing:
/pricingpage lists plans - (M) Frontend signup: flow to choose plan + integrate with own gateway
- (S) Decide gateway: Stripe / Asaas / Mercado Pago
- (M) Integration with chosen gateway
- (M) Webhook receiver for confirmed payment
- (M) Update of
TenantSubscription.Statusbased on payment - (M) Default handling (suspends tenant after X days)
- (S) Frontend: tenant invoice history (in dashboard area)
- (M) Create Customers projects (Domain, Application, Infrastructure, Api, Contracts)
- (M) Configure correct references
- (M) Domain:
-
Customer.cs(TenantEntity) -
CustomFieldDefinition.cs(TenantEntity) -
CustomFieldValue.cs(Value Object) - Enums: CustomerStatus, CustomFieldType (Text, Number, Date, Boolean, Select, Email, Phone, Document)
- Domain events
- Errors
-
- (M) Contracts:
-
ICustomersService.cs - DTOs
- Integration events
-
- (L) Application features:
-
CreateCustomerCommand+ Handler + Validator (with custom fields) -
UpdateCustomerCommand -
DeactivateCustomerCommand -
GetCustomerByIdQuery -
ListCustomersQuery(with search, pagination, filters) -
DefineCustomFieldCommand(tenant admin) -
UpdateCustomFieldCommand -
DeleteCustomFieldCommand -
ListCustomFieldsQuery - Mappers (Mapperly)
-
ICustomerRepository,ICustomFieldDefinitionRepository
-
- (M) Infrastructure:
-
CustomersDbContext - Configurations (Customer with custom fields as JSON column)
- Repositories
-
CustomersService(Contracts impl) - Initial migration
-
CustomersModule.cs
-
- (M) Api:
-
CustomersController -
CustomFieldsController -
CustomersApiModule
-
- (L) Frontend:
- Customers list page (TanStack Table)
- Modal/page to create customer (dynamic form with custom fields)
- Edit customer page
- Custom fields management page (tenant admin)
- Client validation (Zod) based on custom fields definitions
- (S) Unit + integration tests
- (M) Create Payments projects
- (L) Domain:
-
TenantPlan.cs(TenantEntity) — plan tenant offers to its customers -
Subscription.cs(TenantEntity) — Customer ↔ TenantPlan link -
Invoice.cs(TenantEntity) -
Charge.cs(TenantEntity) -
GatewayAccount.cs(TenantEntity) -
TenantPixKey.cs(TenantEntity, encrypted) -
NotificationPolicy.cs(TenantEntity) -
NotificationRule.cs -
NotificationSchedule.cs(TenantEntity) -
NotificationTemplate.cs(TenantEntity) - Enums: BillingInterval, SubscriptionStatus, InvoiceStatus, ChargeStatus, PaymentMethod, NotificationChannel, NotificationMode, NotificationTrigger, GatewayProvider, GatewayAccountStatus
- Documented state machines
- Domain events
- Errors
-
- (M) Contracts:
-
IPaymentsService.cs - DTOs
- Integration events (InvoicePaid, ChargeCreated, etc.)
-
- (XL) Application features:
- TenantPlan CRUD (
CreateTenantPlanCommand, etc.) - Subscription:
-
CreateSubscriptionCommand(subscribe customer to plan) -
CancelSubscriptionCommand -
GetSubscriptionByIdQuery -
ListSubscriptionsQuery
-
- Invoice:
-
GenerateInvoiceFromSubscriptionCommand(recurring job) -
GetInvoiceByIdQuery -
ListInvoicesQuery -
MarkInvoiceAsPaidCommand(manual mode)
-
- Charge:
-
CreateChargeCommand -
MarkChargeAsPaidCommand(manual mode) -
ProcessChargeWebhookCommand(gateway mode)
-
- Pix Keys:
-
RegisterTenantPixKeyCommand(encrypted) -
ListTenantPixKeysQuery
-
- NotificationPolicy:
-
CreateNotificationPolicyCommand -
UpdateNotificationPolicyCommand -
GetTenantPolicyQuery
-
- NotificationTemplate:
-
CreateTemplateCommand - Seed of default templates (friendly reminder, due date, overdue, payment thanks)
-
- Gateway abstraction:
-
IPaymentGateway.csinterface -
ManualPaymentGateway.cs(always available, generates GP-XXXX identifier) -
AsaasPaymentGateway.cs(subaccount + Pix/Card billing)
-
- Mappers, Validators, Repositories
- TenantPlan CRUD (
- (L) Infrastructure:
-
PaymentsDbContext - Configurations (PixKey encryption via converter)
- Repositories
-
PaymentsService - Asaas SDK integration (HttpClient + Polly resilience)
- Webhook signature validation HMAC
- Initial migration
- Background jobs:
-
GenerateInvoicesJob(daily 06:00 BRT) -
ProcessNotificationSchedulesJob(hourly) -
OutboxProcessorJob(every 10s)
-
-
PaymentsModule.cs
-
- (M) Api:
-
TenantPlansController -
SubscriptionsController -
InvoicesController -
ChargesController -
PixKeysController -
NotificationPoliciesController -
NotificationTemplatesController -
WebhooksController(POST /api/webhooks/asaas) -
PaymentsApiModule
-
- (XL) Frontend:
- TenantPlans page (CRUD)
- Subscriptions page (list, create associating customer + plan)
- Invoices page (list, manually mark as paid)
- Invoice detail (with WhatsApp deep link wa.me button)
- NotificationPolicy configuration
- NotificationTemplate editor
- TenantPixKeys management
- Asaas onboarding (subaccount) — white-label flow
- (M) Unit + integration tests
- (M) Rate limiting configured per tenant + per IP
- (M) Audit log for sensitive actions (refund, cancellation, value change)
- (M) Automatic Azure SQL backup configured (point-in-time restore)
- (M) Terms of use and privacy policy (publish before launch)
- (M) LGPD/GDPR: implement personal data deletion (LGPD Art. 18)
- (M) Internal status page (even if simple —
/health/readyexposed publicly) - (M) Application Insights alerts (error rate, latency, webhook failures)
- (S) Documentation for tenants (FAQ, tutorials)
- (S) Internal technical documentation (runbooks)
- ✅ Tenant signs up, chooses plan, pays Luga's subscription via own gateway
- ✅ Tenant creates customers (with custom personalized fields)
- ✅ Tenant defines billing plans and associates customers
- ✅ System automatically generates invoices according to periodicity
- ✅ Tenant manually marks invoices as paid OR receives via Asaas
- ✅ Billing notifications generated and sent (email + manual WhatsApp)
- ✅ 1-3 beta tenants using in real production
- ✅ Test coverage >80% in Domain and Application
- ✅ No data leaks between tenants in E2E tests
- ✅ Performance OK: p95 of requests <500ms
- ✅ Basic tenant documentation available
| # | Risk | Probability | Impact | Mitigation |
|---|---|---|---|---|
| 1 | Microsoft Entra External ID too complex for SMB | Medium | High | Robust custom claims provider; ultra simple signup; E2E flow tests |
| 2 | Asaas API unstable or slow subaccount approval | Medium | High | ManualPaymentGateway always works as fallback; document avg time |
| 3 | Custom fields JSON column causes slow queries with volume | Low | Medium | Computed indexes in SQL Server; fallback to EAV table if becomes problem |
| 4 | Multi-tenancy: bug leaks data between tenants | Low | CRITICAL | Mandatory E2E tests for every CRUD; ArchUnitNET; double code review |
| 5 | Poor performance of Mapperly + EF Core in large queries | Low | Medium | Regular profiling; query splitting; AsNoTracking where possible |
| 6 | Container App cold start affects UX | Medium | Medium | min_replicas=1 in production; staging stays at 0 |
| 7 | Azure SQL Serverless cold start after pause | High | Low | auto_pause_delay=1h in prod; warmup during business hours |
| 8 | Azure costs running away | Medium | Medium | Azure Cost Management alerts; weekly review for first 3 months |
| 9 | MediatR licensed lib (paid version) | Confirmed | Medium | Current free version still works; plan fork or alternative if needed |
| 10 | Small team (1 dev) delays MVP | High | Medium | Aggressively cut scope; early beta releases for feedback |
| 11 | LGPD: not meeting data deletion deadlines | Low | High | Implement deletion flow in Phase 1; document process |
| 12 | Asaas webhook loses messages | Medium | High | Idempotency via unique ExternalEventId; manual replay via dashboard |
A checklist item is considered done when:
- ✅ Code implemented and compiling without warnings
- ✅ Unit tests covering new logic
- ✅ Integration tests if feature touches persistence or API
- ✅ ArchUnitNET passes
- ✅ Code review approved (own dev if solo, with pair if in team)
- ✅ Documentation updated if public contract changed (Contracts or API)
- ✅ Migration reviewed if schema changed
- ✅ Staging deploy works
- ✅ Smoke test in staging passes
- ✅ Item marked as
- [x]in this PLAN.md
For after MVP is running, in likely order:
- Mobile app (Expo) with login + basic dashboard + mark payment
- More sophisticated default handling (dunning policies)
- CSV customer import
- Report export (CSV, PDF)
- Multi-gateway: Pagar.me or Mercado Pago as second provider
- Basic customer portal (V4 anticipated if feedback asks)
- Documents module (DMS)
- Signatures module (electronic signature)
- Actions engine (generic automation)
- Automated WhatsApp via Z-API
- Public API for integrations (with docs in Scalar)
- Dedicated CRM module
- NF module (NFS-e)
- Complete end customer portal
- Unified messaging (Talk)
- Schedule (appointments)
- Cash (financial/income statement)
- Extension marketplace (V3+)
- Mark items as
- [x]as delivered - Add new items in phases as you learn
- Move items between phases if priority changes (but record in history)
- Add new decisions in section 2 (ADRs)
- Update TBDs as decided
- Review risks every sprint
- History of important changes at the bottom of this file
- 2026-05-03: Initial creation of PLAN.md consolidating all architecture, stack, and roadmap decisions.