Final Architecture and Domain Boundaries
This document is the implementation-ready source of truth for Tov+ architecture and domain boundaries.
1. Purpose
This document is the implementation-ready source of truth for Tov+ architecture and domain boundaries.
It defines:
- the system's top-level conceptual model
- what belongs in a domain, module, capability, or interface
- the scopes at which data and behavior live
- how modules are installed, enabled, configured, and authorized
- which dependency directions are allowed
- which design patterns are mandatory or forbidden
This document resolves ambiguities left intentionally high-level in prior product context documents. Future implementation tasks should follow this document unless a later decision log entry explicitly supersedes it.
2. Core product principle
Tov+ is an occasion-first platform for planning and operating complex events.
The root system sentence is:
An Occasion contains Events and Actors, is extended by Modules, governed by Permissions, supported by Communications and Assets, enhanced by Capabilities like Localization, Collaboration, and Publishing, and connected outward through Interfaces like APIs, Webhooks, and Integrations.
The practical consequence is:
- the product root is the occasion, not the event
- actors are the unified participation model
- modules are the feature layer
- permissions are centrally evaluated
- communications and assets are shared domains, not per-module implementations
- capabilities provide reusable cross-cutting power
- interfaces expose or connect the system without changing its internal ownership boundaries
3. Glossary
Occasion
The top-level workspace and coordinated experience. It owns the shared context across all events and participants.
Event
A time/place/audience subcontext inside an occasion. Events are lightweight scopes, not the feature root of the system.
Actor
Any participant or operational entity inside an occasion, including people, groups, vendors, households, and teams.
Domain
A top-level business ownership boundary with durable concepts, records, invariants, and policies that many features may depend on.
Module
An installable product feature that adds user-facing business functionality to an occasion and can be enabled per event.
Capability
A reusable cross-cutting system power that supports multiple domains and modules but is not itself the primary feature surface.
Interface
An externally facing connection surface used to expose Tov+ or connect it to external systems.
Resource
A concrete entity that can be acted on, authorized, audited, searched, exported, or associated with a scope.
Installation
The act of attaching a module definition to an occasion so it can be configured and later enabled for events.
Enablement
The act of activating an installed module for a specific event context.
Grant
A permission rule that allows a principal to perform an action on a resource within one or more scopes.
Principal
The acting identity in an authorization decision. Tov+ supports user, guest, integration, and system principals.
4. Top-level architecture
4.1 Domain map
Top-level product domains:
- Occasions
- Events
- Actors
- Modules
- Permissions
- Communications
- Assets
Cross-cutting capabilities:
- Localization
- Collaboration
- Publishing
External interfaces:
- APIs
- Webhooks
- Integrations
Supporting platform concerns:
- audit
- workflows
- automation
- search
- analytics
- background jobs
- exports
- tagging/classification
4.2 Architecture shape
The architecture is intentionally layered:
- Occasion is the root workspace.
- Events provide scoped contexts inside an occasion.
- Actors provide the unified participant graph for the occasion.
- Modules add feature behavior to the occasion and optionally to specific events.
- Permissions govern access to every sensitive action and resource.
- Communications and Assets provide shared infrastructure domains used by modules and core flows.
- Capabilities provide reusable cross-cutting mechanics that can power domains or modules.
- Interfaces expose or connect the system to external consumers and partners.
4.3 Classification rule
Use these strict decision rules:
- A feature is a
domainwhen it owns foundational business records and invariants that multiple features rely on. - A feature is a
modulewhen it is an installable product surface with occasion-level installation and event-level enablement semantics. - A feature is a
capabilitywhen it provides reusable mechanics to many domains/modules and should not be installed as an end-user feature by itself. - A feature is an
interfacewhen it exists primarily to expose Tov+ outward or connect external systems inward.
Examples:
- Timeline is a module because it is a feature surface enabled per event.
- Publishing is a capability because it powers invitations, signage, seating charts, and exports across multiple modules.
- Communications is a domain because messaging records, templates, delivery state, and notification preferences are shared system data.
- Integrations are interfaces because they connect external systems through controlled, scoped contracts.
5. Domains
5.1 Occasions
Role: Occasion is the root business workspace.
Owns:
- occasion identity, slug, branding, lifecycle state
- default locale and time zone
- shared settings and defaults
- installed module set
- shared communications context
- shared asset context
- shared permission context
- top-level actor graph membership
Does not own:
- module-specific business records
- event operational details
- per-resource authorization logic
Rules:
- guest access resolves from the occasion first
- all event participation is contextualized by an occasion
- modules are installed on occasions, never directly on free-standing events
5.2 Events
Role: Event is a lightweight scoped context within an occasion.
Owns:
- title, timing, location, visibility, status
- invited/relevant audience scope references
- enabled module list
- event-specific configuration overrides
- event-specific publication state where relevant
Does not own:
- the actor graph
- reusable messaging or file infrastructure
- module definitions
- root occasion branding/defaults
Rules:
- events are children of occasions, never roots
- events can narrow audience, visibility, and configuration
- major feature logic belongs in modules or shared domains, not in the event model itself
5.3 Actors
Role: Actors represent every person or operational entity participating in an occasion.
Owns:
- actor identity inside an occasion
- actor type
- actor attributes and preferences
- relationships between actors
- memberships of people into households, groups, or teams
- assignments of actors to scoped responsibilities
- invitation targets and participation references
Does not own:
- authentication credentials
- generalized authorization grants
- module business records beyond actor references
Rules:
- actors are occasion-scoped
- a platform user may link to multiple actors
- actor graph structure is first-class and cannot be flattened into a contact list
5.4 Modules
Role: Modules are installable feature surfaces.
Owns:
- module definitions and contracts
- installation records
- configuration schemas
- enablement records
- dependency declarations
- module-specific business data and workflows
Does not own:
- generic permission engine behavior
- generic file/media management
- generic messaging infrastructure
- occasion or event core records
Rules:
- modules are installed on occasions
- modules are enabled on events
- modules may add occasion-scoped data, event-scoped data, or actor-linked data, but only within their feature boundary
- modules must declare the domains, capabilities, interfaces, and other modules they depend on
5.5 Permissions
Role: Permissions is the cross-cutting authorization domain.
Owns:
- principals and access context evaluation inputs
- roles as convenience bundles
- grants as enforcement units
- scope-aware policy evaluation
- resource/action authorization decisions
- module access surfaces and resource-level policies
Does not own:
- authentication credentials
- UI-only visibility state
- module business workflows
Rules:
- backend authorization is the source of truth
- modules may declare required permission surfaces but may not privately invent bypass logic
- permission checks must evaluate action plus scope plus resource, not broad role names only
5.6 Communications
Role: Communications is the shared messaging and delivery domain.
Owns:
- channels
- message templates
- deliveries
- message threads
- reminders/campaigns
- communication logs
- notification preferences
- provider-agnostic delivery abstractions
Does not own:
- module-specific communication business rules
- feature-specific visibility policy
Rules:
- modules consume communications services and records instead of rebuilding them
- communications stores delivery and messaging state, while modules store the feature intent that triggered messaging
5.7 Assets
Role: Assets is the shared file and media domain.
Owns:
- uploads and storage abstraction
- metadata and transform metadata
- attachment associations
- visibility hooks
- ownership references
- derivative generation references
Does not own:
- feature-specific approval workflows unless generic
- module business semantics for why an asset matters
Rules:
- assets are referenced by modules and domains; they are not duplicated into per-module file systems
- assets own file/media lifecycle mechanics while modules own business usage rules such as approval, placement, or publishability
6. Capabilities
6.1 Capability definition
A capability provides reusable mechanics that power multiple product surfaces but should not be modeled as an installable feature by default.
Decision rule:
- if the main value is reusable mechanics consumed by multiple domains/modules, classify it as a capability
- if the main value is an installable end-user workflow, classify it as a module
6.2 Localization
Role: Localization powers locale-aware UI and content behavior across the product.
Supports:
- occasion default language
- actor language preference
- localized content variants
- formatting rules
- fallback behavior
- translation readiness/status patterns
Must not be implemented as:
- a standalone module
- UI labels only
6.3 Collaboration
Role: Collaboration powers structured multi-actor contribution and shared ownership patterns.
Supports:
- assignment
- claiming
- contribution state
- deadlines
- comments/discussion hooks
- visibility and ownership patterns
Common usage:
- powers modules like potluck, volunteer coordination, shared planning boards, and collaborative checklists
6.4 Publishing
Role: Publishing powers generation of branded digital or print outputs.
Supports:
- template composition
- localization-aware output
- asset composition
- actor-specific variable injection
- QR and coded payload generation
- export-ready artifacts such as PDFs
Common usage:
- powers invitations, signage, menus, seating charts, handouts, and guest-specific printables
6.5 Capability interaction rule
Capabilities may:
- support top-level domains
- support modules
- support interfaces
Capabilities may not:
- replace occasion/event/actor ownership
- become hidden domain models with uncontrolled data ownership
7. Interfaces
7.1 Interface definition
An interface is an inbound or outbound connection surface between Tov+ and the outside world.
Decision rule:
- if the primary purpose is external access, external notification, or external system connection, classify it as an interface
7.2 APIs
Role: Controlled access surface for frontend apps, partner clients, and programmatic consumers.
Rules:
- APIs expose domain and module functionality through stable contracts
- APIs must respect permissions and scope rules
- APIs do not redefine ownership boundaries; they expose them
7.3 Webhooks
Role: Outbound event notifications to external consumers.
Rules:
- webhook events are derived from domain/module state changes
- webhook payloads must never bypass permissions by leaking unauthorized data
- delivery and retry behavior belongs to communications/background job infrastructure, not to business modules directly
7.4 Integrations
Role: Scoped external principals and adapters that connect Tov+ to external systems.
Rules:
- integrations behave like constrained external apps, not trusted superusers
- integrations may consume APIs and emit/receive webhooks
- integration mapping logic belongs to the integration boundary, not to core domains
8. Supporting platform concerns
These concerns are important but are not top-level product ontology.
8.1 Audit
Purpose: immutable or durable records of who changed what and when.
Placement rule:
- audit attaches to domain/module actions but does not redefine their ownership
8.2 Workflows
Purpose: explicit multi-step business process orchestration.
Placement rule:
- workflows coordinate domain/module state transitions
- workflows are not a replacement for domains or permissions
8.3 Automation
Purpose: rule-driven or scheduled action triggers.
Placement rule:
- automation triggers work against domains/modules through explicit contracts
- automation does not bypass permissions or module lifecycle rules
8.4 Search
Purpose: retrieval and discovery across authorized content.
Placement rule:
- search indexes domain/module data
- search is read-oriented infrastructure, not source-of-truth storage
8.5 Analytics
Purpose: measurement, reporting, and product/operational insight.
Placement rule:
- analytics consumes events emitted by domains/modules
- analytics never becomes the operational source of truth
8.6 Background jobs
Purpose: asynchronous execution for deliveries, publishing, processing, sync, and retries.
Placement rule:
- jobs execute work for domains/modules/capabilities/interfaces
- job queues do not own the business model they process
8.7 Exports
Purpose: structured data/package extraction for users or partners.
Placement rule:
- exports are generated from domain/module data through publishing or interface patterns as appropriate
8.8 Tagging and classification
Purpose: generic labels or typed classification applied across resources.
Placement rule:
- tagging/classification may be shared infrastructure
- it must not replace actor relationships, permissions, or module-specific business state when those are semantically required
9. Scope boundaries
9.1 Occasion scope
Belongs at occasion scope when it:
- defines the shared workspace identity or defaults
- applies across multiple events
- must remain stable even if event membership changes
- installs or configures modules for the whole occasion
- governs the occasion-wide actor graph
Examples:
- occasion branding
- default locale/time zone
- installed modules
- shared guest portal configuration
- shared communications templates
- shared assets like invitation art or cover image
9.2 Event scope
Belongs at event scope when it:
- differs by event timing, place, audience, or operational setup
- controls whether an installed module is active in that event
- represents event-specific visibility or publication state
Examples:
- ceremony schedule
- reception seating enablement
- event-specific RSVP deadlines
- event-specific vendor access
9.3 Actor scope
Belongs at actor scope when it:
- describes an actor's identity, preferences, relationships, or participation references within the occasion
Examples:
- actor profile attributes
- language preference
- dietary accessibility needs
- household membership
- vendor category
9.4 Module installation scope
Belongs at module installation scope when it:
- exists once per occasion/module pair
- configures the module's presence in the occasion
- declares module-level defaults before event activation
Examples:
- module installed state
- install-time configuration
- dependency satisfaction status
- planner-selected defaults for the module
9.5 Module enablement scope
Belongs at module enablement scope when it:
- represents event-level activation of an installed module
- contains per-event module configuration or state gates
Examples:
- gallery enabled for brunch but not rehearsal dinner
- timeline enabled only for the main event
- seating enabled with event-specific publish state
9.6 Resource scope
Belongs at resource scope when it:
- applies to a concrete record or artifact rather than an entire occasion/event/module
- must support fine-grained authorization or lifecycle
Examples:
- a specific gallery asset
- a specific seating chart
- a specific timeline item
- a specific invitation package
9.7 Scope resolution rule
When deciding scope, place data at the highest shared scope that preserves correctness without forcing duplication.
Therefore:
- do not put occasion-wide defaults on every event
- do not put event-specific operational state on the occasion root
- do not put generic actor identity inside module tables
- do not put resource-specific permissions only at role level
10. Module system model
10.1 Module definition
A module definition is the static contract for a feature type.
It must declare:
- module key
- purpose
- supported scopes
- required domains
- required capabilities
- module dependencies
- interface dependencies if any
- install-time config schema
- event enablement config schema
- required permission surfaces
10.2 Installation lifecycle
The lifecycle is final and mandatory:
- A module definition exists in the registry.
- An occasion installs the module.
- Installation-time dependency validation runs.
- Occasion-level configuration is stored.
- One or more events enable the installed module.
- Event-level configuration is stored if needed.
- Permissions and invitations determine which actors/principals can access the module's surfaces or records.
10.3 Installation semantics
Installation means:
- the occasion has adopted the module
- shared configuration can exist
- the module can be referenced by other modules in the occasion
- event enablement becomes possible
Installation does not mean:
- every event uses the module
- every actor may access the module
- permissions are automatically granted
10.4 Enablement semantics
Enablement means:
- an installed module is active for a specific event
- the event can hold event-level config for that module
- event-specific rules and visibility can apply
Enablement does not mean:
- the module bypasses permissions
- every invited actor sees the module
- other events inherit the same activation
10.5 Actor access semantics
Actor access to a module requires all applicable conditions:
- the module is installed on the occasion
- the module is enabled for the relevant event when event context is required
- the actor or linked principal is within the relevant audience/context
- the permissions domain grants the action on the resource/scope
- invitation or participation state allows the surface where applicable
10.6 Dependency validation
Dependency validation must check:
- required domains exist in the platform
- required capabilities are available
- required modules are installed before a dependent module is installed or enabled, depending on the dependency type
- required permission surfaces are declared
- incompatible configuration is rejected before runtime use
10.7 Actors vs modules vs permissions
Use these ownership rules:
actor identitybelongs in Actors.actor relationshipsbelong in Actors.actor assignmentsbelong in Actors when they are generic cross-system assignments; module-specific assignment details may live in the module while referencing actors.invitationsare occasion/event participation records rooted in Actors plus Occasions/Events, not module-owned identity substitutes.access grantsbelong in Permissions.module participation databelongs in the module, but must reference actors and respect central permissions.
Concrete examples:
- Household membership belongs in Actors.
- "Guest may edit this seating chart" belongs in Permissions.
- "Guest selected meal option in RSVP" belongs in the RSVP module.
- "Vendor assigned to timeline item" may use an actor assignment reference plus timeline module state.
11. Dependency rules
11.1 Allowed dependency directions
The allowed conceptual dependency directions are:
- frontend apps -> sdk, ui, auth, types, config, utils, approved domain-facing packages
- backend/server/api -> domain, modules, permissions, capabilities, communications, assets, integrations, auth, types, utils
- backend/server/worker -> domain, modules, permissions, capabilities, communications, assets, integrations, auth, types, utils
- modules -> domains, capabilities, permissions contracts, communications, assets, other declared modules
- capabilities -> shared low-level packages and supporting domains where necessary
- interfaces -> domains, modules, permissions, capabilities, communications, assets
- communications/assets -> shared low-level packages and their own internal subcomponents
11.2 Forbidden dependency directions
The following are forbidden:
- domains depending on frontend app UI
- permissions depending on frontend apps
- assets depending on a specific module implementation
- communications depending on a specific module implementation
- event domain becoming the dependency root of the whole system
- actors depending on module-specific participant models
- modules bypassing permissions through direct trust assumptions
- integrations bypassing API/permission constraints
- capabilities depending on a specific frontend surface as their source of truth
11.3 Dependency principle
Shared foundational layers may be depended on broadly. Feature layers may depend downward on foundations. Foundations must not depend upward on specific feature implementations.
In practical terms:
- many modules may use assets
- assets must not know gallery, seating, or invitations as hard dependencies
- many modules may use communications
- communications must not embed RSVP-specific or chat-specific policy
12. Classification framework
Use this framework when classifying a new feature.
12.1 Step 1: Is it foundational shared business ownership?
If yes, classify as a domain.
Examples:
- actor graph
- permission grants
- asset metadata
- communication delivery logs
12.2 Step 2: Is it an installable user-facing feature?
If yes, classify as a module.
Examples:
- timeline
- seating
- gallery
- FAQ
- RSVP
- reminders
12.3 Step 3: Is it reusable mechanics used by multiple features?
If yes, classify as a capability.
Examples:
- publishing
- localization
- collaboration
12.4 Step 4: Is it an external connection surface?
If yes, classify as an interface.
Examples:
- public API
- outbound webhooks
- print-vendor integration
12.5 Real Tov+ feature classifications
Timeline-> module. It is enabled per event and may use actors, communications, and publishing.RSVP-> module. It is an installable participation workflow and may depend on forms.Forms-> module. It is an installable structured data-collection feature.Gallery-> module powered by the Assets domain.Chat-> module powered by the Communications domain.Reminders-> module powered by the Communications domain and background jobs.Seating-> module powered by Actors and Publishing.Invitation QR packages-> module-driven output powered by the Publishing capability plus Assets and Actors.Localized invitation copy-> content implemented by a module or domain surface using the Localization capability.Potluck/shared planning-> module powered by the Collaboration capability and Actors.Printer sync-> integration interface that consumes publishing output through controlled permissions.Searchable guest lookup-> search concern indexing Actors and related module data; not its own top-level domain.Export guest CSV-> export concern powered by interfaces/publishing, not a separate business domain.
12.6 Escalation rule
If a feature seems to be both a module and a capability:
- classify the end-user workflow as the module
- classify the reusable mechanics beneath it as the capability
If a feature seems to be both a domain and a module:
- classify shared source-of-truth records as the domain
- classify installable experience/workflows on top as the module
13. Anti-patterns
The following must not happen:
- Event becomes the root model for product flows or storage ownership.
- Guest UX is modeled as a collection of isolated event apps instead of an occasion portal.
- Participation is split into separate guest/vendor/helper data models that bypass Actors.
- Modules hide authorization logic internally or rely on frontend checks as enforcement.
- Modules reimplement communications sending, delivery tracking, or message preference systems.
- Modules reimplement file uploads, media storage, or transform pipelines.
- Localization is treated as UI labels only.
- Publishing is implemented separately inside each module with no shared capability.
- Integrations are treated as trusted backdoors rather than scoped principals.
- Assets or communications hard-code knowledge of a specific module's business rules.
- Guest flows inherit planner complexity or require full account creation for basic access.
- Resource-level access is approximated only with broad roles and no scoped grants.
- Tagging/classification is misused as a substitute for actor relationships, permissions, or actual business state.
- Background jobs become a second business logic layer disconnected from domain/module rules.
14. Open questions (only if truly unresolved)
No architectural questions are intentionally left unresolved by this document.
Implementation details still remain for future tasks, including exact schema shape, package APIs, and transport contracts, but the ownership and boundary decisions above are considered final.
15. Final summary
Tov+ is organized around an occasion-rooted domain model with lightweight events, a unified actor graph, centrally evaluated permissions, shared communications and assets domains, installable modules as the feature layer, cross-cutting capabilities for reusable mechanics, and interfaces for external connection.
The non-negotiable rules are:
- occasion first
- actors unify participation
- modules carry feature behavior
- permissions remain centralized
- communications and assets are shared top-level domains
- capabilities power reuse without becoming ad hoc modules
- interfaces connect outward without changing internal ownership
- dependency directions flow from apps and features toward shared foundations, not the reverse