Skip to content

Architecture Decision Records

Architecture Decision Records (ADRs) document the significant architectural choices made across our projects. Each record captures the context, options considered, the decision, and its consequences.

Why We Write These

When you join a project or review a pull request, you often ask "why is it done this way?" These records answer that question. They capture not just what was decided, but why — including what we considered and rejected.

How to Read an ADR

Each ADR follows the same structure:

  • StatusProposed (under discussion), Accepted (implemented or being implemented), Superseded (replaced by a newer decision)
  • Context — The problem or situation that prompted the decision
  • Options Considered — Alternatives we evaluated, with reasons for rejection
  • Decision — What we chose and how it works
  • Consequences — The trade-offs we accepted, both positive and negative

Decision Index

Kendo

#DecisionStatusSummary
1Audit Logging SystemAcceptedPer-entity audit tables with hash chains for ISO 27001 compliance
6Two-Tier AuthorizationAcceptedRoute-level model permissions + action-level interaction permissions
3AI Interaction LoggingAcceptedThree-channel logging for outbound AI calls, MCP tools, and AI runs
8Multi-TenancyAcceptedDIY database-per-tenant for 3 fixed companies
13Adapter-Store PatternAcceptedCustom reactive store factory over Pinia for 15+ domain stores
25GitHub Integration SplitAcceptedSplit GithubService into OAuth handshake + bearer-token-parametrized API client; per-call token argument

Brick Inventory

#DecisionStatusSummary
4Import AtomicityAcceptedSave-what-you-can with honest reporting for API imports

Emmie

#DecisionStatusSummary
22Schedule End Date InclusiveAcceptedSchedule.end_date is the last active day; canonical predicates use inclusive <= / >=
23Schedule Mutation ChokepointAcceptedSingle Action owns Schedule date mutation; wrapping normalizer, schema unchanged

Cross-Project

#DecisionStatusSummary
2Cascade Deletion & Soft DeletesAcceptedModel declares, Action executes, tests verify. No ON DELETE CASCADE.
9Unified ResourceData PatternAcceptedCustom ResourceData base class replaces Laravel's JsonResource
11Action Class ArchitectureAcceptedfinal readonly Actions with single execute() method, explicit DI
12FormRequest → DTO FlowAcceptedType-safe pipeline from HTTP validation to business logic
14Domain-Driven Frontend StructureAcceptedVertical slices by business domain, not technical layers
16Config Attribute InjectionAccepted#[Config] attribute for all config access, config() helper prohibited
17Page Integration TestsAcceptedMount domain pages with real components, mocked services, separate coverage accounting
19Explicit Model HydrationAcceptedBan $fillable/$guarded, require explicit property assignment in Actions
15ADR GovernanceAcceptedSingle source of truth at adrs.script.nl
18ISMS Information SystemAcceptedLaravel + Vue ISMS with policies as markdown, operational data in PostgreSQL
20Input/Result DTO SplitAcceptedSplit DTOs by usage direction at the Action boundary — arch tests enforce
21PHPStan Rules PackageAcceptedCanonical war-room PHPStan rules distributed as script-development/phpstan-warroom-rules Composer package
24Automated External ProvisioningAcceptedAsync + provider-abstracted + retain-on-failure + audit-mandatory + Tier-1 retry + flag-gated for tenant-resource provisioning

Architecture documentation for contributors and collaborators.